I have an actor system "Main" running potentially forever. This main actor understands "Snapshot" or "Stop" messages (defined by me).
I would like to create a bash script that, while Main actor is running, launches a second (short lived) system, or actor, or whatever and sends a snapshot or stop message to the Main actor.
With akka classic that was very easy with actorSelection from a secondary actor
ActorRef mainActorRef = Await.result(system.actorSelection("akka.main.actor.path").resolveOne(timeout));
mainActorRef.send(new StopMessage() or new SnapsthotMessage());
What is the analogous and hopefully equally easy solution in akka typed?
Ok, let's try to sort this mess a bit... First of all, your question is highly unclear:
In the title, you ask for something based on two JVMs, but in the text you ask for a "second (short lived) system, or actor, or whatever". No clue if multiple JVMs are a requirement or just an idea to solve this. Additionally, your example code is something that - disregarding clustering - works in one JVM and you also only mention a second "actor" there.
So, if the requirement is using two JVMs, then I would suggest making it more clear in what way, why, etc. Then people can also actually provide help for that part.
For now, let me assume you want to simply have...
A (typed) actor system
...that can somehow process StopMessage/SnapshotMessage...
...both of which can be triggered from the outside
The way you can do this very simply is the usual typed way:
Define a RootGuardian actor that accepts those two messages (that actor is basically what the implicit /user actor was in classic) - you have to do that for your Typed actor system anyway (because to setup a typed actor system, you supply the behavior of the RootGuardian).
Let it create the needed child actors to process those messages (either at start or when needed). Of course, in your simple example, the root guardian can also process these messages itself, but an actorsystem with only one actor is not a very typical use-case.
Let it delegate the messages to the appropriate child actor(s)
Add a simple api endpoint to call system.tell ( ... ) to send the message into the system, where your RootGuardian actor will delegate it correctly.
Use curl to call your api endpoint (or use any other way to communicate with your application, there are dozens, but most of them are outside the scope of akka itself)
As a general idea, Akka Typed tends to be much more strict about who can send what messages where. In Akka classic, it was easy to basically send everything everywhere and find and access any actor from everywhere, including outside the system. Unfortunately, this "freedom" leads to a huge amount of problems and was thus severely limited in Typed, which makes for clearer contracts and better defined message flows.
Of course, in a highly complex system, you might, for example, want to use a Receptionist instead to find the target actor for your specific message, but since the question was for a simple application, I would skip that for now.
You can, of course, also add ways to get your ActorRefs outside the system, for example by using the Ask Pattern to implement something like an actor discovery in the RootGuardian, but there is simply no need to try to circumvent the concepts of Akka Typed by re-implementing ActorSelection.
Obviously you also could use clustering, start up a 2nd JVM, connect it to the cluster, send the message and shut it down again, but we can assume that this would be overkill and very, very slow (waiting for long seconds while starting up the app, connecting to the cluster, etc. just to then use a few milliseconds to send the message).
If you absolutely want a 2nd JVM there, you can, of course, for example, create simply REST client that sends the message and start that, but... curl exists, so... what for?
So, tl;dr: The "analogous and hopefully equally easy solution" is system.tell( new StopMessage() );, which is basically the same in akka typed as the code for akka classic you provided. Obviously, implementing the actor system in a way that this code works, is the (slightly) more tricky part.
Related
I become desperate, I develop a simple multi-user chat in Java based on the client-server principle. I already wrote a basic multi-threaded server application and it works great. My problem is the client on the basis of the Swing GUI Toolkit. A basic UI with a runtime loop for receiving messages in the background. My problem is that I want to separate the socket logic from the UI, this means that in the best case I've two different classes one for the socket runtime loop and another to manage the UI. Because of the problem, that the runtime loop must notify/add messages to the UI, they depend on each other.
MessengerView is my main class which contains the swing ui and all depended components. At the moment this class contains also the socket logic, but I want to extract them to an external class.
ClientRuntime the class which should hold the socket logic...
My question is, how could I separate them and how could I connect them? For example I tried swing-like events with registering of methods like this:
addListener(MessageArrivedListener listener);
emitMessageArrivedEvent(String message);
The problem is, that it is very confusing if the count of events raises! As already said my second options is to hold socket logic and ui design in one class, but I think it's a bad idea because it makes it very hard to write unit tests for it or to find bugs...
In my time with C++ I used sometimes friend-classes for this issue, because this makes it possible to access class members of other classes! But this solution is often also very confusing and I found no such option for Java.
So are there any other possibilities to hold the connection between the swing widgets and the socket logic, without storing them in the same class (file)?
how could I separate them and how could I connect them?
Connect them with BlockingQueue - this the first choice when choosing ways to connect threads.
ClientRuntime class must start 2 threads: one takes requests from the blocking queue and sends them to the server, and the second constantly reads the messages from the server through the socket and sends them to the UI thread. The UI thread has already input blocking queue for messages: it is accessed by SwingUtilities.invokeLater(Runnable);. The ClientRuntime class does not access UI queue directly: it calls a method from MessengerView and passes what it received from the socket, a binary array or json string, and that UI method converts it to some Runnable which actually updates the UI.
they depend on each other
Well, they don't really. The "socket" layer only cares about been started, running, posting some messages and stopping.
How all that actually get done/handled it doesn't care about, it just "starts" when told, processes input/output messages, posts notifications and "stops" when asked to.
This is basically an observer pattern, or if you prefer, a producer/consumer pattern.
So the socket layer needs to define a "protocol" of behaviour or contract that it's willing to work with. Part of that contract will be "how" it generates notifications about new messages, either via an observer or perhaps through a blocking/readonly queue - that's up to you to decide.
As for the UI, it's a little more complicated, as Swing is single threaded, so you should not block the UI with long running or blocking operations. This is where something like a SwingWorker would come in handy.
It basically acts a broker between the UI and the mechanism made available by the socket layer to receive messages. Messages come from the socket layer into the SwingWorker, the SwingWorker then publishes them onto the UI's event thread which can then be safely updated onto the UI
Maybe start with Concurrency in Swing and Worker Threads and SwingWorker
My question is, how could I separate them and how could I connect them? For example I tried swing-like events with registering of methods like this:
The problem is, that it is very confusing if the count of events raises!
I don't think so (IMHO). What you want to do is focus on the "class" of events. For example, from the above, you have "life cycle" events and you have "message" events. I'd start by breaking those down into two separate interfaces, as those interested in "message" events probably aren't that interested in "life cycle" events, this way you can compartmentalise the observers.
The important concept you want to try and get your head around is the proper use of `interfaces to define "contracts", this becomes the "public" view of the implementations, allowing you devise different implementations for different purposes as you ideas change and grow. This decouples the code and allows you to change one portion without adversely affecting other parts of the API
I have to coordinate 5 separate microservices e.g. A,B,C,D,E
I need to create a coordinator which might monitor a queue for new jobs for A. If A completes ok then a rest request should be sent to B then if everything is ok (happy path) then C is called all the way down to E.
However B,C etc might fail for one reason or another e.g. end point is down or credentials are insufficient causing the flow to fail at a particular stage. I'd like to be able to create something that could check the status of failed job and rerun again e.g. lets try B again, ok now it works the flow would then continue.
Any tips or advice for patterns / frameworks to do this. I'd like something fairly simple and not over complex.
I've already looked briefly at Netflix Conductor / Camunda but ideally I'd like something a bit less complex.
Thanks
W
Any tips or advice for patterns / frameworks to do this. I'd like something fairly simple and not over complex.
What you describe is the good ol' domain of A,B,C,D and E. Because the dependencies and engagement rules between the letters are complex enough, it's good to create a dedicated service for this domain. It could be as simple as this overarching service just being triggered by queue events.
The only other alternative is to do more on the client side and organize the service calls from there. But that isn't feasible in every domain for security reasons or other issues.
And since it sounds like you already got an event queue going, I'll not recommend one (Kafka).
One way apart from Camunda, Conductor is to send a event from Service A on some Messaging Queue (eg. lets say kafka ) which provides at least once delivery semantics.
Then write a consumer which receive the event and do the orchestration part (talking to service B,C,D,E).
As these all operations needs to be idempotent.First before starting orchestration create a RequestAgg. for the event from A and keep updating its state to represent where you reach in your orchestration journey.
Now even if the other services are down or your node goes down. This should either reach the end or you should write functions to rollback as well.
And to check the states and debug , you could see the read model of RequestAgg.
I'm trying to use GPars in Java to handle messages of a few types.
There is one actor for each message type.
But message processing takes a lot of time, while messages keep coming. I need to ignore upcoming messages (just throw them away) while the actor is busy.
How do I know if an GPars actor is busy? I know about Actor.isActive() method, but I'm not too sure that it is the thing (the JavaDoc is pretty ambiguous and unclear) and I couldn't find any useful info ether.
There's no built-in way to determine this, I'm afraid. You'd have to implement a busy-controlling algorithm yourself, perhaps based on CountdownLatches.
In general, this can be problematic, as an actor can only process one message at a time, whatever solution you have to do this, will have limitations. For instance you can have an actor within an actor, a supervisor and a worker.
The worker actor is the one which actually does the work. What happens is work is sent to the supervisor. The supervisor has a boolean variable such as isBusy, which is initially false. When work is received the supervisor sets the variable to true, and passes the work on to the worker. When the work is finished the worker sends the result back to the supervisor and the supervisor sets the isBusy to false and returns the result.
If another message comes in whilst the isBusy is false the supervisor can just send a message back such as an isBusy message, or do nothing which is what you say you want.
Note that if the worker crashes, or restarts, the isBusy will still be true. You will need to think about this solution, if it will meet your needs. There maybe a mailbox which would be better for this I don't know.
Whatever you do, you should try your best to avoid creating situations where you could leave your actor system in a bad state, best of luck.
Does Akka 2 provide a way to determine the number of actors of a certain type active at a certain time in the system?
I've was looking for something like
int actorCount = getContext().count(MyActor.class)
OR
Props props = Props.create(MyActor.class, "actorName")
...
int actorCount = getContext().count(props)
OR
getContext().actorSelection("/path/to/actor").count()
I've just started playing with the akka framework in Java, so please bear with me.
In one of my Akka applications (my first, and not one I'd hold up as a shining example of how to write such systems), I implement a low-water / high-water work generation strategy driven by a heartbeat. The low and high water marks are defined in terms of number of work actors active, each of which does one thing and is created by a manager. That manager keeps track of started and as-yet unompleted workers and can respond to requests from the work generator for the current activity count. The response to these inquiries provides the information as to whether work in progress has fallen below the low-water mark and new work should be generated.
It's kind of crude and in a new system I'm working on now the connections between work generation and work execution, as well as checkpoint logging, is done in a more continuous, less "batch-oriented" manner. This system is about to be deployed, so at the moment I can't say for certain how it will perform, but I'm pretty sure it will exhibit better behavior than the earlier system. It's also inherently more complicated that the earlier system in how it generates, performs and records the work it does.
[Going to put this also as a valid answer]
If the actor who needs the count is not the parent and/or cannot retrieve the ActorRefs of the target actors, then the following might be an alternative.
Counting the number of actors of a certain type can be done by sending a "head count" message, holding an ActorRef array, passing each actor. Then each target actor can add it's ActorRef to that list and forward the message. But this depends on the nature of the system and works only if you know beyond any doubt that you don't have any actors spawning up during the "head count".
I have a problem which I believe is the classic master/worker pattern, and I'm seeking advice on implementation. Here's what I currently am thinking about the problem:
There's a global "queue" of some sort, and it is a central place where "the work to be done" is kept. Presumably this queue will be managed by a kind of "master" object. Threads will be spawned to go find work to do, and when they find work to do, they'll tell the master thing (whatever that is) to "add this to the queue of work to be done".
The master, perhaps on an interval, will spawn other threads that actually perform the work to be done. Once a thread completes its work, I'd like it to notify the master that the work is finished. Then, the master can remove this work from the queue.
I've done a fair amount of thread programming in Java in the past, but it's all been prior to JDK 1.5 and consequently I am not familiar with the appropriate new APIs for handling this case. I understand that JDK7 will have fork-join, and that that might be a solution for me, but I am not able to use an early-access product in this project.
The problems, as I see them, are:
1) how to have the "threads doing the work" communicate back to the master telling them that their work is complete and that the master can now remove the work from the queue
2) how to efficiently have the master guarantee that work is only ever scheduled once. For example, let's say this queue has a million items, and it wants to tell a worker to "go do these 100 things". What's the most efficient way of guaranteeing that when it schedules work to the next worker, it gets "the next 100 things" and not "the 100 things I've already scheduled"?
3) choosing an appropriate data structure for the queue. My thinking here is that the "threads finding work to do" could potentially find the same work to do more than once, and they'd send a message to the master saying "here's work", and the master would realize that the work has already been scheduled and consequently should ignore the message. I want to ensure that I choose the right data structure such that this computation is as cheap as possible.
Traditionally, I would have done this in a database, in sort of a finite-state-machine manner, working "tasks" through from start to complete. However, in this problem, I don't want to use a database because of the high volume and volatility of the queue. In addition, I'd like to keep this as light-weight as possible. I don't want to use any app server if that can be avoided.
It is quite likely that this problem I'm describing is a common problem with a well-known name and accepted set of solutions, but I, with my lowly non-CS degree, do not know what this is called (i.e. please be gentle).
Thanks for any and all pointers.
As far as I understand your requirements, you need ExecutorService. ExecutorService have
submit(Callable task)
method which return value is Future. Future is a blocking way to communicate back from worker to master. You could easily expand this mechanism to work is asynchronous manner. And yes, ExecutorService also maintaining work queue like ThreadPoolExecutor. So you don't need to bother about scheduling, in most cases. java.util.concurrent package already have efficient implementations of thread safe queue (ConcurrentLinked queue - nonblocking, and LinkedBlockedQueue - blocking).
Check out java.util.concurrent in the Java library.
Depending on your application it might be as simple as cobbling together some blocking queue and a ThreadPoolExecutor.
Also, the book Java Concurrency in Practice by Brian Goetz might be helpful.
First, why do you want to hold the items after a worker started doing them? Normally, you would have a queue of work and a worker takes items out of this queue. This would also solve the "how can I prevent workers from getting the same item"-problem.
To your questions:
1) how to have the "threads doing the
work" communicate back to the master
telling them that their work is
complete and that the master can now
remove the work from the queue
The master could listen to the workers using the listener/observer pattern
2) how to efficiently have the master
guarantee that work is only ever
scheduled once. For example, let's say
this queue has a million items, and it
wants to tell a worker to "go do these
100 things". What's the most efficient
way of guaranteeing that when it
schedules work to the next worker, it
gets "the next 100 things" and not
"the 100 things I've already
scheduled"?
See above. I would let the workers pull the items out of the queue.
3) choosing an appropriate data
structure for the queue. My thinking
here is that the "threads finding work
to do" could potentially find the same
work to do more than once, and they'd
send a message to the master saying
"here's work", and the master would
realize that the work has already been
scheduled and consequently should
ignore the message. I want to ensure
that I choose the right data structure
such that this computation is as cheap
as possible.
There are Implementations of a blocking queue since Java 5
Don't forget Jini and Javaspaces. What you're describing sounds very like the classic producer/consumer pattern that space-based architectures excel at.
A producer will write the jobs into the space. 1 or more consumers will take out jobs (under a transaction) and work on that in parallel, and then write the results back. Since it's under a transaction, if a problem occurs the job is made available again for another consumer .
You can scale this trivially by adding more consumers. This works especially well when the consumers are separate VMs and you scale across the network.
If you are open to the idea of Spring, then check out their Spring Integration project. It gives you all the queue/thread-pool boilerplate out of the box and leaves you to focus on the business logic. Configuration is kept to a minimum using #annotations.
btw, the Goetz is very good.
This doesn't sound like a master-worker problem, but a specialized client above a threadpool. Given that you have a lot of scavenging threads and not a lot of processing units, it may be worthwhile simply doing a scavaging pass and then a computing pass. By storing the work items in a Set, the uniqueness constraint will remove duplicates. The second pass can submit all of the work to an ExecutorService to perform the process in parallel.
A master-worker model generally assumes that the data provider has all of the work and supplies it to the master to manage. The master controls the work execution and deals with distributed computation, time-outs, failures, retries, etc. A fork-join abstraction is a recursive rather than iterative data provider. A map-reduce abstraction is a multi-step master-worker that is useful in certain scenarios.
A good example of master-worker is for trivially parallel problems, such as finding prime numbers. Another is a data load where each entry is independant (validate, transform, stage). The need to process a known working set, handle failures, etc. is what makes a master-worker model different than a thread-pool. This is why a master must be in control and pushes the work units out, whereas a threadpool allows workers to pull work from a shared queue.