Reactor Multiplexing: Dispatch event to just exactly one subscriber - java

I am playing a bit with Reactor right now. While trying to build a small demo game (just to get accustomed to the framework), I need the ability to have multiple "entities" subscribed to a publisher. But I also need each published event to reach exactly one subscriber. For now, they all always get it. I know that I could build some "latch" into this event so that all but one subscriber discard it.
But I think in the sea of features, there might be an operator or something that already does exactly this...
Multiple subscribers to a single publisher. Each subscriber would need to apply a different filter too though.
Each event from the publisher going only to a single subscriber in no particular order... (The filter does not guarantee uniqueness, there could be multiple subscribers using the same filter).
Randomness is cool but not required (since the subscriber will unsubscribe upon receiving this event). You might have guessed that this will be the kill signal for the entity ;).
Thanks!

Looks like UnicastProcessor does the trick.

Related

How many Consumers on a VertX EventBus Channel?

I want to publish a message on a EventBus channel and receive a response from everyone who's listening to that channel. The thing is, how to I know everyone has already responded if I don't know how many responses to expect?
I assume I need to know how many consumers there are in order to know that I already got all responses or not.
Is there any way to know how many consumers are currently "listening" to a Vert.x EventBus address?
EventBus works on a "best effort" basis, so even if you could track the number of subscribers, there is a chance that some of them would never return your message.
If you're still inclined to try it, there are a couple of ways I can thin of. None are really recommended, but I'll try to highlight the pros and cons anywya.
One is to get a reference to handlerMap inside EventBusImpl through reflection.
https://github.com/eclipse-vertx/vert.x/blob/master/src/main/java/io/vertx/core/eventbus/impl/EventBusImpl.java#L48
If you get it once, when your application starts, that should have much impact on the performance. Of course that will break at runtime if Vert.x team decides to as much as change the name of the field.
Another option is to use vertx.sharedData(), for example getLocalMap(). All consumers will add themselves to the map, and producer will check the map to figure out how many consumers are listening. The problem with that implementation:
Lots of logic to implement this
Unregistering consumers is hard (there's no guarantee that consumer will be able to unregister itself)

Jade - which behaviour for an events loop?

I'm implementing a Multi-Agent System in JADE. Events are placed in a queue and will sequentially happen. An EventManager agent should go through the queue and handle them one by one.
So my EventManager should take the first event - send out messages to the other agents, whom will "solve" the event.
After the first event has been completely solved should the second event be taken and solved. (etc. for many more events)
My problem thus is which behaviour to use to implement this?
I thought about a sequential behaviour but that uses multiple behaviours sequentially while this is one behaviour (grabbing the event and solving it) multiple times, but only after the previous one has been done.
I like the idea of the generic behaviour but instead of the switch a for loop. Unfortunately it is absolute necessary that the previous event is completely solved before the next one is opened.
How to implement this ?
One important thing is here, how the communication between agents is orgainzed?
Do you get answers from all agents when they did their work? This can be archived by using communication protocols like ContractNet or something more handy.
If you have received all answers, you can start a new 'job' behaviour (can be an OneShotBehaviour for example), wait for agent answers again and finally, decide if to start a new job or terminate.

Axon Framework: Saga project with compensation events between two or three microservices

I have a question about Axon Saga. I have a project where I have three microservices, each microservice has his own database, but the two "Slave" microservice has to share his data to the "Master" microservice, for that I want to use the Axon Saga. I already asked a question about the compensation, when something goes wrong, and I have to deal with the compensation by myself, it is ok, but not ideal. Currently I am using the DistributedCommandBus to communicate between the microservices, is it good for that? I am using the Choreography Saga model, so here is what it is look like now:
Master -> Send command -> Slave1 -> Handles event
Slave1 -> Send back command -> Master -> Handles event
Master -> Send command -> Slave2 -> Handles event
Slave2 -> Send back command -> Master -> Handles event
If something went wrong then comes the compensating Commands/Events backwards.
My question is has anybody did something like this with Axon, with compensation, what the best practices for that? How can I retry the Saga process? With the RetryScheduler? Add a github repo if you can.
Thanks, Máté
First and foremost, let me answer your main question:
My question is has anybody did something like this with Axon?
Shortly, yes, as this is one of the main use cases of for Sagas.
As a rule of thumb, I'd like to state a Saga can be used to coordinate a complex business transaction between:
Several distinct Aggregate Instances
Several Bounded Contexts
On face value, it seems you've landed in option two of delegating a complex business transaction.
It is important to note that when you are using Sagas, you should very consciously deal with any exceptions and/or command dispatching results.
Thus, if you dispatch a command from the "Master" to "Slave 1" and the latter fails the operation, this result will come back in to the Saga.
This thus gives you the first option to retry an operation, which I would suggest to do with a compensating action.
Lastly, with a compensating action, I am talking about dispatching a command to trigger it.
If you can not rely on the direct response from dispatching the command, retrying/rescheduling a message within the Saga would be a reasonable second option.
To that end, Axon has the EventScheduler and DeadlineManager.
Note that the former of the two publishes an event for everyone to see.
The latter schedules a DeadlineMessage within the context of that single Saga instance, thus limiting the scope of who can see a retry is occurring.
Typically, the DeadlineManager would be my preferred mode of operation for thus, unless you require this 'rescheduling action' to be seen by everybody.
FYI, check this page for EventScheduler information and this page for DeadlineManager info.
Sample Update
Here's a bit of pseudo-code to get a feel what a compensating action in a Saga Event Handler would look like:
class SomeSaga {
private CommandGateway commandGateway;
#SagaEventHandler(assocationValue = "some-key")
public void on(SomeEvent event) {
// perform some checks, validation and state setting, if necessary
commandGateway.send(new MyActionCommand(...))
.exceptionally(throwable -> {
commandGateway.send(new CompensatingAction(...));
});
}
}
I don't know your exact use case, but from this and your previous question I get the impression you want to roll back, or in this case undo, the event if one of the event handlers cannot process it.
In general, there are some things you are able to do. You can see if the aggregate that applied the event in the first place has or can have the information to check whether the 'slave' microservice should be able to handle the event before you apply it. If this isn't practical, the slave microservice can also apply a 'failure' event directly on the eventbus to inform the rest of the system that a failure state has occurred that needs to be handled:
https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling/dispatching-events#dispatching-events-from-a-non-aggregate

Implementing an event bus with priorized subscribers and concurrent modification

I have several parts of my application, that need to react to events triggered from somewhere else, so the first thing I thought about would be an event bus. These are the requirements I see:
The subscriber method should be typesafe
Implementing an interface (like Subscriber<T>) is not a problem
A subscriber should also receive any events of subtypes to the class it's registered to
Subscribers should be able to be registered with a priority (a simple int) or a default priority hardcoded somewhere in the code. When posting an event, the subscribers will be called in order. The events are mutable and some of their fields will change between subscribers
Each thread will have its own event bus and I will manually register all subscribers, so there's no need for static access
While receiving an event, it should be possible for a subscriber to unsubscribe without raising a ConcurrentModificationException
Bonus requirements I might need down the line:
Register new subscribers while handling events
Send events while receiving one. Those will be processed synchronously before proceeding with the current task
The option to "pool" events that currently have no subscriber and manually process them later (maybe by passing a Consumer).
Guava Eventbus probably does most of those things except for the priority. I can create a simple prioritized subscriber queue by using a TreeSet, but I'm not sure how to integrate it into Guava and I don't know if I want to depend on the whole library just for the bus.
Also, I might need a CopyOnWriteArrayList for the concurrent stuff (adding/removing while iterating), but I don't know about the performance implications. On that note, there probably won't be more than 10-15 subscribers at a time.
Normal events are not designed to be mutable. You should stick with immutable data. Also subscribers are not intendet to be called within a certain order or to interact with another.
For your usecase you could build different event busses for each priority. A subscriber could handover a copy of the modified event to the next priority bus.

What does share operator do in RxJava? When should I use it?

I know that share() is a replacement of publish().refCount().
Then from the RxJava wiki:
Observable.publish( ) — represents an Observable as a Connectable Observable
ConnectableObservable.refCount( ) — makes a Connectable Observable behave like an ordinary Observable
This make me confused. If after publish().refCount(), it just behave like an ordinary Observable, why should I use it, how does this api make sense?
You're right - Observable.share is just a shortcut for publish().refCount(). I think that description you have quoted above is not entirely clear as ConnectedObservable.refCount does a little bit more :)
If you transform your Observable to ConnectableObservable - it will not emit items (even if something is subscribed) unless explicitly called ConnectableObservable.connect - it basically defers execution of subscribe method and prevents from executing it multiple times for every subscriber. This technique is often used to make sure that all subscribers are subscribed before observable starts emitting items (in other words - after everyone has subscribed - connect() method is called).
If you have more than one subscriber (what often happens), you have to handle their subscriptions and unsubscriptions and this is where things are getting tricky. This is why refCount() was introduced. This operator returns new Observable, keeps track of how many subscribers are subscribed to it and stays connected as long as there is at least one subscription. It will also automatically connect when the first subscriber appears.
PS. I'm learning how to use RxJava, if I am wrong - please point it out!

Categories