I've been looking into Elixir and Akka recently, and that got me thinking: what's the equivalent in Clojure?
I found a couple of "message throughput comparison" posts about agents vs actors, but they were from 8 years ago
One answer used to be agents ... but that's not quite the same thing (agents don't seem to have their own logic, they're "acted upon" by external code)
Another somewhat recent answer was Pulsar fibres (closer, but ... is that still maintained?)
(I am aware that it's possible that I'm "asking the wrong question here", hopefully this isn't too open ended)
Rich Hickey in his 2008 talk "Clojure Concurrency" explicitly distinguishes agents from actors, mentioning several ways that they are different from each other. Search for "agent" and "actor" in the transcript of this talk if you want to find some of those comments quickly: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ClojureConcurrency.md
More here on clojure.org on the differences between agents and actors: https://clojure.org/about/state#actors
Another conversation from someone that knows more about the original Hewitt actor model than I do, apparently, that may be useful to read: http://www.dalnefre.com/wp/2010/06/actors-in-clojure-why-not/
My understanding is that if you want Erlang-style actors, you basically need unreliable message queues between threads/processes. Between different processes, there are any number of ways to get unreliable message passing, none built into Clojure, but all available via Java interop.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I realize this isn't an ideal question, but i'll do my best to explain it :)
Firstly, the scenario is that I have been tasked for creating a simulation of a building with multiple elevators.
Let's assume my building consists of between 2 and 5 elevators, and an arbitary number of floors. The goal here was to allow "People" to board the elevators and travel to different floors.
The key point here is running each of the elevators concurrently.
I have managed to do this in C++ with a Thread for each elevator. What I am struggling to do is think of a simple way to do this with Message Passing in Erlang. I am not asking for a code answer, but moreso, an explanation of how i could approach this problem using message passing. I have of course attempted to read information on the topic, but it's confusing me.
I understand thus far that the threads must communicate via passing Messages to each other. Any help clarifying an approach on this is greatly appreciated. This is not graded homework or anything, and is an exercise for my knowledge.
Final Question:
How can I model a building with multiple elevators programmed to operate independently using Message Passing (in Erlang).
Instead of maintaining a shared state, you give each process its own state, and if anything changes you send messages with the update (and associated data) to all relevant processes
What Daniel is calling a process is an Erlang process, not a thread. They might seem like threads, but they are at least as different as they are similar... So it's really best to call them processes.
You need to be careful not to carry with you a C mind set when you come to design Erlang solutions. The point of Erlang is that it's a different paradigm, and whilst Erlang itself is implemented in C and thus everything you do in Erlang is ultimately run in a C thread, it's important to largely forget that and work with the Erlang paradigm instead.
In C are something to be managed, they are tricky and bite you when you aren't keeping a careful watch on them. Erlang processes are wonderful, you can to all intents and purposes spawn an unlimited number of them, and they don't really require any looking after as such.
In your lift scenario, as Daniel said, spawning a process for each lift is a reasonable design. One of the things to consider with Erlang is that numnbers in cases like this don't really matter, once you write a module to model your lift, you can spawn 2 to 5 of them, or 2 to 5 million of them, and you usually find with Erlang that it makes very little difference.
I'm not saying you can't design a broken implementation, but honestly, once you get used to Erlang you'll find it really lends itself to rapid development without the usual parallel and concurrency pitfalls.
As you progress your lift scenario, the right way to take it forwards is to get to know OTP, use something like a gen_server for your lifts, and a supervisor to spawn them dynanmically (or not) from it. If your lift crashes the process will then automatically get replaced/restarted. This is analagous to a lift breaking down (process has died; lift is unavailable) and the repair engineer coming and fixing it (process restarted; lift is available again). What happens to any people in the lift when it breaks down is perhaps a more advanced topic, for which there are a few possible solutions.
Akka seems like a dream come true. Sadly, like so much other software, the documentation and examples are lacking in some major ways. Since the whole point of the thing is to provide non-blocking, parallel io, why would they provide a hello world that just returns a string. Here's a nutty idea: have an agent for each word, translate it into another language by calling something on the web, then returning the results.
I went around in circles today reading documentation about Futures and Promises. One working example would have obviated the whole thing.
I have done a lot of concurrent programming with Future in the java concurrency package. For some reason, the Akka stuff just seems way too complicated. I am doing something very close to what I described above: getting a request and having several agents fulfill it over the web. I took the original generated project that has the Master and the Listener as the starting point and it works fine, I just can't figure out a simple way to return the aggregated results. I have a play-mini method that is getting called. From there, I am calling a method on a class that sends the messages to the agents and when they are done running, their results get aggregated and the Listener gets called. How do I compose a Future out of that? All the documentation says don't block but we are having to return from a REST request.
Does anyone know of such an example? Super simple. Thanks.
I ended up doing composed Futures. Works pretty well. When you create a sequence, you still have to call Await, but the parallel execution still returned in ⅓ of a second so I'm happy.
As to getting Actors to handle a REST request, I thought about passing it a Future and then waiting on that? Might play around with some of those possibilities, but what I have now works.
The other question this experience raised for me is how to implement Ask in an Actor. Not covered in the docs and given the name, searching for Akka and ask is pretty much useless.
Here's a suggestion: each of these mechanisms should be shown in sequence diagrams. How hard would that be to do??
Still really excited about Akka. It's awesome to finally be able to do Actor-based programming.
I'm new in node.js. I'm testing socket.io for real time messaging. I love it and I want to use. I have a question. How many concurrency can run in Node.js server ? Our program will be approximately 100 concurrency. So, I'm worry about that.
I found another real time messaging server , APE. Which one is better ? I love node.js because it's easy to learn and easy to write. But I couldn't find discussion about concurrency in node.js server. My friend company is using APE and it can control around 2000. So, I want to know about node.js server.
Without having any benchmarks to back this up--since both are event-driven (i.e. epoll on Linux), I would imagine that you'll see comparable results for both (at least 10K concurrent users). That being said, performance is likely to be much more affected by the frequency of messages than the number of concurrent connections, since that's where the implementations really differ.
For a real-world example and discussion about node.js Comet performance, see Amir Salihefendic's excellent blog post here: http://amix.dk/blog/post/19577 (you can follow the links in that post to other posts that are fantastic as well).
Notice that one of the versions he wrote was in C using libevent (epoll) which is what APE uses as well. Also, note that APE's website claims that it can handle over 100,000 concurrent users.
If you really want to understand the problems associated, you might find the famous "C10K problem" article interesting (do a google search for "C10K problem").
In the end, it probably comes down to how many requests per second you expect, and how many machines you have, and which language you prefer to code in. If you're only expecting around 100 concurrent users, I think you'll be just fine using any platform you want. That being said, I highly recommend using node.js--just for sheer enjoyment if nothing else. :-)
I've been trying to find anything that discusses when you should favor the use of monads over actors (in concurrency scenarios), but I've found nothing. In particular, I'm wondering about the use of the Reactive Extensions (LINQ to Events) vs. F#'s MailboxProcessor. Please give examples in addition to any philosophical reasoning you might have.
Update
For better context, the Reactive Extensions implement the continuation monad in the form of IObservable/IObserver. I'm not necessarily saying I have to use F#, just that F# has a concrete "actor model" available in a .NET language in the form of MailboxProcessor<'T>.
What I'm trying to understand is when to use a monad (in this case a continuation monad) vs. an actor model for concurrency purposes. Where the monad (as I understand it) doesn't introduce state, the actor has its own internal state that is modified as necessary to provide protected access.
I've seen a number of examples of using both: Rx and node.js (CPS, not really the continuation monad) vs. F#'s MailboxProcessor and Scala's Akka framework. I just don't know why you would choose one over the other.
I'm not sure that the question makes sense as phrased - there are many different monads (e.g. the identity monad, the list monad, the option monad, ...), most of which have nothing to do with concurrency. Furthermore, it would be helpful to know more about the particular scenario that you're dealing with - "concurrency" is a bit of a nebulous topic. Depending on what you're trying to achieve, F#'s async workflows (which are built on the Async monad) might be your best bet.
If you're using F#, I'd recommend against using LINQ-to-anything directly, since those libraries have a very alien feel when accessed via F#. You could, however, create pleasant F# wrappers (such as the existing Seq and Observable modules). Additionally, for monadic types, you could create a computation expression builder (e.g. you could create a builder using the Reactive Extensions which would enable you to use computation expressions to build and compose IObservables).
Please excuse my newbie-ness as I'm just learning F#.
I'm intrigued to see the use of RX in place of a MailboxProcessor, if you have any links to relevant materials.
With my limited understanding; I would choose MbP's in my own code as events are a bit messy to set up in F# (from what I can take from this article: MSDN). And you need events for RX to hook into right?
Where as with a MbP all I need is a discriminated union of messages, a list of functions I wish to be executed when a given message is received. And the mail box processor that handles this.
This all looks pretty neat in the code. I can bunch my MbP's together in a module then my "object" module looks like
Record
Message DU
Wrapper with some getters and setters that post data to the MbP
For me this looks a lot neater than it would If I wrote my code with events as described in that MSDN article I linked to.
Though I am just an F# junior so I may be a miles off with my reckoning and it is a look-&-feel thing rather than a suitability-for-purpose choice (as I'm not qualified to make that call, yet)
Would you accept answers from the Scala world?
If you seek "a purely functional alternative to actor model" then please see this great post from Paul Chiusano's blog
pchiusano.blogspot.ro/2010/01/actors-are-not-good-concurrency-model.html
(archived here: http://archive.is/NxNLc)
and some references below:
http://noelwelsh.com/programming/2013/03/04/why-i-dont-like-akka-actors/
Actors do not Compose
Akka’s Actors are not Usefully Typed
The type system is the reason we use Scala.
https://opencredo.com/akka-typed/
Unfortunately, the current API suffers from a few drawbacks, which are to a good degree associated with the lack of type safety
http://doc.akka.io/docs/akka/snapshot/scala/typed.html
Status of this Project and Relation to Akka Actors
Akka Typed is the result of many years of research and previous attempts (including Typed Channels in the 2.2.x series) and it is on its way to stabilization, but maturing such a profound change to the core concept of Akka will take a long time
A side-effect of this is that behaviors can now be tested in isolation without having to be packaged into an Actor, tests can run fully synchronously without having to worry about timeouts and spurious failures. Another side-effect is that behaviors can nicely be composed and decorated
Composable application architecture with reasonably priced monads
https://youtu.be/M258zVn4m2M?t=1955
https://youtu.be/M258zVn4m2M?t=1986
The concept of "function passing style" from Heather Miller might be key to a distributed functional programming model.
SF Scala: Heather Miller, Function-Passing Style, A New Model for Distributed Programming
Update 12/2018 : now we can use Aecor which provide the means to:
implement business domain logic with a functional programming model and
use an Akka based runtime
"behaviors belong to the domain layer and runtime is out there in the infrastructure layer."
Source: https://pavkin.ru/aecor-part-3/, http://aecor.io
I'm going to respond to my own question and say you should use both. This is based on Don Syme's post. A MbP uses the Async computation to do its work, and the Async is a thread-aware continuation monad. Looks like you can use it by itself for some uses, but the MbP definitely requires it.
I don't really like this answer, and I'd be happy for someone to respond with a better explanation of when to use each.
Updated:
See MiniRx, which is now apart of FSharpx, for an implementation of an Rx-style monad implemented using MailboxProcessor. As MailboxProcessor is itself implemented using the async monad, these pieced to indeed work together. They are just different means of abstraction.
Looking for some general advice...
I've been using boost for a while, and I've written several small modules and function (eg: see this SO question) which I think cold be appropriate for inclusion in boost. I've been to the project pages to see about the submission process, but it seems like it's "be on the inside, or don't bother". I can subscribe to the developers mailing list, but I'm not sure I'm qualified to post there: I'm certainly not intimately familiar with all the various boost modules, and not nearly as well-versed in template meta-programming as the people actively participating.
Is there an avenue that I'm missing for "normal" people to send ideas for things which could be incorporated into boost? Or is boost kinda a "open in name only, unless you make it a full-time job" type of project?
I think that you shouldn't hestitate and go to boost-devel. Most likely your code will not be accepted, but it is very likely that you will be able to collect valuable feedback and learn a lot. People there will justify why it can't be accepted in the current form, or how the given functionality could be made more generic, etc. I think that overall it will be beneficial for you.
If you are not comfortable with boost-devel then subscribe and just follow it for some time. And few more personal comments about reading/following the list:
Find out who is who - some people are active only in very narrow fields, while others tend to have a lot to say in many different domains
Create some kind of filtering rules for new mails (the load of the list is rather heavy) - some mails are really not interesting
Observe the review process of the submitted libraries, critical comments, suggestions.
Subscribe to boost-devel, boost and boost-users - they tend to be quite interconnected. You can throw sprit, threads and ublas lists if you are interested in these projects.
I have been following the devel list for some time. I feel as you do: maybe I am not playing in the same league as these people, but nevertheless you do learn quite a bit from the discussions there.
During the time I have been there, I have found some kind of common pattern for submissions: first query for interest in the library, then offer the library for review. Beware of the licensing of your code: if it is not compatible with the boost license most of the people will not even give it a look. Spending time in the review of some proprietary code seems like working for free for someone else.
Also consider writting docs and publishing, make the library accessible in the internet and have others use/look at it. That will boost (no pun intended) your chances.
Why does your stuff have to go straight into boost ? Why not just put it "out there" first with a license you're happy with... if there's enough interest in it from users a "hey this should be in boost" might be the next logical step, or not.
I tried submitting my UTF-8 CPP library to Boost. Started by subscribing to their dev mail list and sent a couple of informal review requests, but felt it leads nowhere so I gave up and never submitted a formal review request.
Good luck with your submission.
Did you look at http://www.boost.org/development/submissions.html?