You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is probably not exactly an issue with bacon itself but since I'm new to FRP I would like to hear opinions.
For the project I'm working on I came to a stage where I need a kind of feedback mechanism. Since I still think mostly in imperative programming terms, I can't figure out a way to avoid it.
Basically I have a simple Requests stream that has to be transformed into Responses stream. This is a node.js project and the requests are actually send over a serial port, thus requests have to be send synchronously. So far I have used .flatMapConcat() which did great in queuing the requests and dispatching them one by one.
But for some technical reasons I have to avoid the queue. I'm not going into details but in short, in specific situations the requests have to be dispatched either immediately or not at all (let's say that executing the queued requests later is of no use).
Of course the logical thing is to use .flatMapFirst() which does exactly the above. My problems started when the requirement emerged that the dropped requests have to be redirected to another stream - for simplicity, let's say to a logger.
I created a property which indicates whether there's an active request and tried to modulate the request stream with it. Here's a simplified diagram:
The problem with this approach is that it introduces a cyclic dependency. When I try to run this I get stack overflow:
RangeError: Maximum call stack size exceeded
at flushDepsOf (...\node_modules\baconjs\dist\Bacon.js:457:21)
at flushDepsOf (...\node_modules\baconjs\dist\Bacon.js:463:9)
at flushDepsOf (...\node_modules\baconjs\dist\Bacon.js:463:9)
I found a way around this by breaking the dependency chain by separating the flow graph with a Bus():
This works as expected since busy no longer seems to be dependent on Requests. But it's little ugly of course.
I looked into the code related to flushDepsOf() and the problem is that the flushed map gets filled in for a given observable only when all it's dependencies are flushed. Of course if the same observable is found somewhere within these dependencies it becomes infinite recursion.
I tried moving the flushed[obs.id] = true; line before iterating through the dependencies. This of course avoids the infinite recursion but probably can cause troubles in some cases.
This is my first ever work with FRP so I don't really know what I'm up against here.
First: is cyclic dependence really a sign of wrong approach to the problem? Feedback mechanisms exist in all domains of engineering, programming, etc, so probably it should be allowed in FRP too. If it is not, is there some trick that can rearrange the flow in a such a way that cycles can be avoided (so far I haven't thought of one)?
Second: if cyclic dependencies are not strictly forbidden, does this mean that bacon can be improved to better handle them (like the solution with moving the flushed line above)?
Thank you!
The text was updated successfully, but these errors were encountered:
This is probably not exactly an issue with bacon itself but since I'm new to FRP I would like to hear opinions.
For the project I'm working on I came to a stage where I need a kind of feedback mechanism. Since I still think mostly in imperative programming terms, I can't figure out a way to avoid it.
Basically I have a simple
Requests
stream that has to be transformed intoResponses
stream. This is a node.js project and the requests are actually send over a serial port, thus requests have to be send synchronously. So far I have used.flatMapConcat()
which did great in queuing the requests and dispatching them one by one.But for some technical reasons I have to avoid the queue. I'm not going into details but in short, in specific situations the requests have to be dispatched either immediately or not at all (let's say that executing the queued requests later is of no use).
Of course the logical thing is to use
.flatMapFirst()
which does exactly the above. My problems started when the requirement emerged that the dropped requests have to be redirected to another stream - for simplicity, let's say to a logger.I created a property which indicates whether there's an active request and tried to modulate the request stream with it. Here's a simplified diagram:
The problem with this approach is that it introduces a cyclic dependency. When I try to run this I get stack overflow:
I found a way around this by breaking the dependency chain by separating the flow graph with a
Bus()
:This works as expected since
busy
no longer seems to be dependent onRequests
. But it's little ugly of course.I looked into the code related to
flushDepsOf()
and the problem is that theflushed
map gets filled in for a given observable only when all it's dependencies are flushed. Of course if the same observable is found somewhere within these dependencies it becomes infinite recursion.I tried moving the
flushed[obs.id] = true;
line before iterating through the dependencies. This of course avoids the infinite recursion but probably can cause troubles in some cases.This is my first ever work with FRP so I don't really know what I'm up against here.
First: is cyclic dependence really a sign of wrong approach to the problem? Feedback mechanisms exist in all domains of engineering, programming, etc, so probably it should be allowed in FRP too. If it is not, is there some trick that can rearrange the flow in a such a way that cycles can be avoided (so far I haven't thought of one)?
Second: if cyclic dependencies are not strictly forbidden, does this mean that bacon can be improved to better handle them (like the solution with moving the
flushed
line above)?Thank you!
The text was updated successfully, but these errors were encountered: