I've read the camunda doc, but I don't find anything about it.
I know it doesn't make sense throw something that nobody will catch, but is it possible?
https://docs.camunda.org/manual/7.7/reference/bpmn20/events/signal-events/
https://camunda.com/bpmn/reference/#events-signal
In the Business Process Model And Notation 2.0 specification(can be found at
https://www.omg.org/spec/BPMN/2.0/), P253, in the Table 10.89 - Intermediate Event Types in Normal Flow:
(Signal) This type of Event is used for sending or receiving Signals. A Signal is
for general communication within and across Process levels, across
Pools, and between Business Process Diagrams. A BPMN Signal is
similar to a signal flare that shot into the sky for anyone who might be
interested to notice and then react. Thus, there is a source of the Signal,
but no specific intended target.
Hope that helps.
Yes this is possible. You can model a throwing signal event when there are no receivers. The event will simply throw the signal and continue the normal flow (without anyone ever using the event).
In contrary to that, the catching signal events can not be used without a throwing signal event. If you use a catching signal event without a throwing signal event the process will stop at this event and will never be able to continue.
Related
I have observed that even if i stop a node or a participant by pressing ctr + C, i.e. terminate it...it still shows in the Admin console or 2 minutes or so. Why isnt it immediately derigestered. Is there a way to do so ?
At shutdown of your application, you should clean up the DDS entities, as demonstrated in this piece of example code. In a nutshell, it invokes the following methods:
DDS_DomainParticipant_delete_contained_entities(participant);
DDS_DomainParticipantFactory_delete_participant(DDS_TheParticipantFactory, participant);
If you do not do that, the DDS discovery process will detect by itself after a while that the Participant has gone. The responsiveness of this mechanism is configurable, as explained in the knowledge base article What settings affect DomainParticipant’s liveliness?
Now pressing Ctrl+C normally will not execute the code described above, because the signal will terminate the process right away. As far as I know, the only way to avoid that is to install a signal handler that invokes that clean-up functionality. Here is a gist with some example code on how to install a signal handler: aspyct/signal.c.
I am implementing an event store. I have defined a SaveEventsConsumer that handles the storage of events in the event store. If I understand correctly CQRS commands should have no response. Nevertheless, there can be concurrency problems when saving events to the event store. I use RabbitMQ. Should the client be notified so it can notify the user for example? How should it be implemented? Using RPC and an error format?
My first approach is:
Client use RPC like style. SaveEventsConsumer notifies the client (success or failure). If an failure occurs (e.g. concurrency) return the exception to the client.
Is this solution aligned to the CQRS pattern? Is a good approach? Is there any other approach? Is there any improvement? Should I use any AMQP header or property to indicate the error (mimicking HTTP error codes)?
Example, in a cluster:
Two instances of the same application modify the same aggregate. These intances should coordinate (externally to the event-store) or is the event-store which has to detect and notify the response?
While it is true you don't return values from a command, an exception can still occur. A concurrency exception is one example. This implies the exception is thrown as part of the processing of a command. This makes sense when you think about it. You don't ever want events published which have not yet been committed to the event store. It follows then that concurrency conflict checking needs to happen as part of the overall command process.
I have a post which may help. You can find it here.
Basically, I have a multi-instance subprocess and want to be able to send some kind of signal to the parent process without terminating all other instances of the subprocess.
Please have a look on this sample process:
The subprocess is a multi-instance subprocess with a cardinality of 3.
i.e. when completing UserTask A, three instances of the subprocess are created. The user then needs to complete Task B three times. Fine.
But when the gateway routes to the "throw signal" event, I want the other two instances keep on running! Currently, all instances of the subprocess are terminated as soon as the signal is thrown.
With the help of the signal, I want to create some more instances of the subprocess after visiting UserTask A again.
How can I model this behavior in BPMN / Camunda?
Thanks in advance!
Chris
It is possible to achieve what you want by declaring the boundary catching signal event to be non-interrupting.
(Having said that, from a pure BPMN perspective an escalation event throw/catch would be a better fit for your case, but it is not yet supported by camunda BPM. So, just be careful not to cause side effects with the signal, because the signals may be received by other catching signal events, too.)
I am working on my first real Go project, a messaging API. I use channels to pass messages and other data between user goroutines and library goroutines that use a thread-unsafe, event-based C protocol library. For details https://github.com/apache/qpid-proton/blob/master/proton-c/bindings/go/README.md
My question is in 2 related parts:
1. What are common idioms for handling errors across channels?
The goroutine at one end blows up, how do I ensure the other end unblocks, gets an error value and doesn't get blocked again later?
For readers:
I can close the channel, but no error info.
I could pass a struct { data, error }
or use a second channel.
Pros & cons? Other ideas?
For writers: I can't close without a panic so I guess I need a second channel. Is this idiomatic?
select {
case sendChan <- data: sentOk()
case err := <- errChan: oops(err)
}
I also can't write after close so I need to store the error somewhere and check before trying to write. Any other approaches?
2. Exposing channels in APIs.
I need channels to pass error info: should I make those channels public fields or hide them in methods?
There is a tradeoff, and I don't have the experience to evaluate it:
Exposing channels lets users select directly, but it requires them to correctly impement the error handling patterns (check for errors before write, select for error as well as write). This seems complex and error-prone but maybe that because I'm not seasoned in go.
Hiding channels in a method simplifies and enforces correct use of the library. But now an async user must create their own goroutine and channel(s). They may just duplicate what the library does already, which is silly. Also there is an extra goroutine and channel on the path. Maybe that's not a big deal, but the data channel is the critical path for my library and I think it has to be hidden along with the error channel.
I could do both: expose the channels for power users and provide a simple method wrapper for people with simple needs. That's more to support but worth it if neither alone can fit all cases.
The standard net.Conn uses blocking methods, not channels, and I wrote goroutines to pump data to my C event-loop channel so I know it can be done, but I did not find it trivial. net.Conn is wrapping sytem calls not channels underneath so "exposing the channels" is not an option. Do any of the standard libraries export channels with error handling? (time.After doesn't count, there are no errors)
Thanks a lot!
Alan
Your question is a bit on the broad side but I'll try to give some guidance based on my experience writing highly concurrent code...
Personally I think making the channel a property of the object that gets initialized in a nice helpful NewMyObject() *MyObject method is good design pattern. It makes it so code using the object doesn't have to do boiler plate set up every time it wants to call some asynchronous method the type offers.
For readers: I can close the channel, but no error info. I could pass a struct { data, error } or use a second channel. Pros & cons? Other ideas?
Let the reader signal to return by closing the abort channel. The reader should simply use the temp, err := <-FromChannel paradigm and move on with execution if the data or error channel has closed. This should prevent the 'send on closed channel' panics error from the workers since they will close their channel and return. When err != nil the reader will know to move on.
For writers: I can't close without a panic so I guess I need a second channel. Is this idiomatic?
Yes. Sadly I was quite pissed of with the uni-directional behavior of channels and though it should be abstracted. Regardless, it's not. In my code I would not define this on the object that does work asynchronously. The paradigm I prefer is to use the closing signal (since sending a on a channel is not one-to-many, only one goroutine will read that). Instead, I allocate the abort channel in the calling code and if things need to shut down you close the abort channel and all the goroutines doing asynchronous work who are listening on that channel do their clean up and return. You should also use a WaitGroup so you can wait for the goroutines to return before moving on.
So my basic summary;
1) let the caller of asynchronous methods signal it's time to stop, not the other way around. A waitgroup is better used to coordinate their returns
2) use a sync.WaitGroup in the calling code to know when your goroutines are finished so you can move on
3) allocate your error channel in the calling code and take advantage of the one-to-many signal produced by closing the channel; if you send on a channel you allocate in the caller, only a single instance will read from it. If you put one on each instance you have to iterate a collection of instances to send the on each.
4) if you have a type that provide async methods that do work in the background, set up the channels to read off of in it's initializer, document the async methods saying where to listen for data, provide an example of a non-blocking select that passes an abort channel into the async method and listens on the methods data and error channels. If you need to kill a single routine you could accomplish this by closing one of the channels it owns rather than killing them all by closing the callers abort channel.
Hopefully that all makes sense.
We've got a CQRS project and are thinking about a way to implement a "catchup", e.g. a new event handler is started and tells the eventstore to replay all events for him.
We're not sure if we should do the replay over the NServiceBus, as there is a real 1:1 connection and no publish/subscribe situation. Also we think that our new consumer is not able to keep up with the publish-speed and its input queue would get stuck.
What's the best practice here?
I've heard of people doing the following:
Have a system of replaying/rebroadcasting the events. Event handlers that have produced projections that have already seen these events ignore the events.
Allow events to be queried directly by the Event Handler when resetting it or when starting a new projection from scratch. This can be done in some systems by reading directly from the event store and in other actor based system an actor abstraction around the source of events may be queried.
From my understanding, option 2 allows for better performance as events can be queried in batches as opposed to being replayed to all listeners individually. These are just my observations without any practical experience to draw on yet.