In general, when designing a system which has multiple events happening in some well pre-defined logical order, are there any benefits to either requesting all necessary timeouts at the beginning of the process, or requesting always only the "next" timeout (or in other words, the timeout for the next event)?
To clarify, I'm talking about a scenario when you want a number of things to happen sequentially.
Event A should happen 3 hours after initialization, Event B 10 hours after initialization, and Event C 48 hours after initialization of some process.
When the process is started, should it request a timeout only for Event A (which would then in turn request a timeout for Event B, and so on), or should it immediately request a timeout for all the Events?
In our case the process might be stopped at any point in time - Thus if it's stopped 5 hours after initialization then Event A should have already happened, and Events B and C should not happen at all.
A process might also in special cases be initiated midway through (ie "Start process 5 hours in", in which case Event B should happen 5 hours later), and the timelines of individual processes might be updated manually (ie "Lets postpone Event B by 2.5 hours for this single process instance).
Any thoughts appreciated,
If I got your scenario ok, you can start this with a saga that is started by an initial message that starts the process, on handling the initial message you would request the timeouts you expect and in the timeout handlers checking whether the other events/operation where handled and acting based on the current state...
Does that make sense?
Related
I have a very simple Saga built with NSB7 using SQL Transport and NHibernate persistence.
The Saga listens on a queue and for each message received runs through 4 handlers. These are called in a sequential order, with 2 handlers run in parallel and the last handler only runs once both the parallel handlers are complete. The last handler writes a record to DB
Let's say for a single message, each handler takes 1 second. When a new message is received, which starts the Saga, the expected result is that 3-4 seconds later the record is written to the DB.
If the queue backs up with say 1000 messages, once they begin processing again, it takes almost 2000 seconds before a new record is created in the last handler. Basically, instead of running through the expected 4 second processing time for each message, they effectively bunch up in the initial handlers until the queue is emptied and then does that again for the next handler and on and on.
Any ideas on how I could improve the performance of this system when under load so that a constant stream of processed messages come out the end rather than the bunching of messages and long delay before a single new record comes out the other side?
Thanks
Will
There is documentation for saga concurrency issues: https://docs.particular.net/nservicebus/sagas/concurrency#high-load-scenarios
I still don't fully understand the issue though. Every message that instantiates a saga, should create a record in the database after the message was processed. Not after 1000 messages. How else is NServiceBus going to guarantee consistency?
Next to that, you probably should not have the single message be processed by 4 handlers. If it really needs to work like this, use publish/subscribe and create different endpoints. The saga should be done with processing as soon as possible, especially under high load scenarios.
I am struggling to find proper setting to delay timeout for workers in RabbitMQ.
By default prefetchCount since the version 2.0 are set to 250 and exactly this amount of messages are being received and processed.
I would like to keep workers busy, until they clear up an entire queue (lets say 10k messages).
I can manipulate this number manually, such as changing default limit or assigning more threads resulting in multiplying default number.
Results are always the same. Once the number is reached, workers stop their job and application finish its execution
o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
I would like them to finish when the queue is empty. Any ideas?
The logger.info("Successfully waited for workers to finish."); happens only in one place - doShutdown(). And this one is called from the shutdown(), which is called from the destroy() or stop().
I somehow think that you exit from your application by some reason. You just don't block the main() to work permanently.
Please, share a simple project we can play with.
I have a program where I start several process instances using a cron. For each process instance I have a maximum time, and if the execution time exceeds it, I have to consider it as failure and use some specific methods.
For now what I did was simply to check, once my process instance has finished, if the elapsed time exceeds or not the given maximum time.
But what if my process instance gets blocked for some reason (e.g. server not responding)? I need to catch this event and perform failure operations as soon as the process gets blocked and timeout is exceeded.
How can I catch these two conditions?
I had a look at the FlowableEngineEventType, but there isn’t a PROCESS_BLOCKED/SUSPENDED type of event. But, even if it were, how do I fire it only if a certain amount of time has passed?
I assume that this is the same question as this from the Flowable Forum.
If you are using the Flowable HTTP Task then have a look at the documentation to see how you can set the timeouts on it and how you can react on errors there. If you are firing GET requests from your own code you would need to write your own business logic that would throw some kind of BpmnError and you would then handle that in your process.
The Flowable Process instance does not have the concept of being blocked, and you have to manually to that in your modelling.
I have an app which continuously reads status updates from a server connection.
All is working well with a stream delegate to handle all the reading and writing asynchronously.
There's no part of the app that is "waiting" for a specific response from the server, it is just continuously handling status updates as they sporadically arrive from the socket. There are no requests on the client side that are waiting for responses.
I'm wondering what the best practice would be for the network activity indicator in this case.
I could turn it on in the stream event handler, and off before we leave the handler, but that would be a very short time (just enough for an non-blocking read or write to occur). Trying this, I only see the faintest flicker of the indicator; it needs to be on longer than just during the event handler.
What about turning it on in the stream delegate, and setting a timer to turn it off a short time later? (This would ensure it's on long enough to be seen, rather than the short time spent in the stream delegate.)
Note: I've tried this last idea: turning on the network activity indicator whenever there's stream activity, and note the NSDate; then in a timer (that I have fired every 1 second), if the time passsed is >.5 second, I turn off the indicator. This seems to give a reasonable indication of network activity.
Any better recommendations?
If the network activity is continuous then it sounds like it might be somewhat annoying to the user, especially if it's turning on and off all the time.
Perhaps better would be to test for lack-of-response up to a certain timeout value and then display an alert view to the user if you aren't getting any response from the server. Even that could be optional if you can provide feedback (like "Last update: 5 mins ago") to the user instead.
I have a saga which represents a long-running work assignment process of a "Person" to a "Case". Several events may kick it off, and at the end of the process we have an assignment confirmation, at which point the saga completes and the Person is assigned to the Case. I would like to have a timeout for this saga so that we don't wait indefinitely for confirmation - definitely a valid business use case. No difficulties there - fairly vanilla.
The twist is that this assignment process can be blocked if someone puts the Case on hold. I have an event I can subscribe to so my assignment saga knows the Case is on hold, but unless I adjust the timeout or suspend it in some way, the assignment saga will likely time out before the Case hold is released. It doesn't make business sense to do this, so I basically want to stop the timeout clock until some other event comes in.
This same issue was mentioned here a couple years ago. Is this still not possible or are there new features in v3.x that would allow it? If not, is it a planned feature?
Thanks!
Why not remove the timeout altogether for the instance when your case is put on hold? Your saga maintains the state of the case and the calculated time when the case would have been due. This could have been set when you created the first timeout. When the case is reactivated, simply calculate the difference in time from the reactivation and the saved "deadline", and create a new timeout for that instance with the difference. You may also want to take into account the time the case was on hold and set a new deadline which you would save back to the instance state.
I don't think there is a way to tab directly to the timer and put the timeout message "on-hold"
I would have that logic inside the timeout handler on the saga. Check if the case is on hold and request another timeout without ending the saga.