Towards an actor framework for Haskell

I’d also like to voice my support for this and say I am very much looking forward to it.

If at some point you are able to coordinate some work let us know!

1 Like

Cheers! I’ve been working on some of the basics in my hack branch (long-running PR for feedback here). Some example usage can be found here. The output of the latter is currently something like

Ponger started, waiting for Ping
Pinger started
Sending Ping
Waiting for Pong
Received Ping, sending Pong
Done, received 1 pings
Got Pong, done
Caught: Exit {exitSender = ProcessId 0, exitReceiver = ProcessId 3, exitLink = True, exitReason = Nothing}
Got: Down {downMonitorRef = MonitorRef {monitorRefId = MonitorRefId 0, monitorRefMonitoree = ProcessId 5, monitorRefMonitor = ProcessId 4}, downProcessId = ProcessId 5, downReason = Nothing}
3 Likes

After some more coding, I’m fairly happy with what’s there now in the PR. I’d appreciate some code-review and feedback, especially on one critical function: spawnImpl in Process.hs. While almost everything the library does uses STM and is, hence, quite simple to reason about, spawnImpl implements the actual spawning of new processes in threads (using async), then monitoring the process thread for exit/failure, at which point any linked or monitoring processes must be notified.

Given asynchronous exceptions, that’s tricky. I believe things should be “fairly OK” since the library never shares Asyncs/ThreadIds outside of spawnImpl, hence, no outside code except for the RTS can throwTo anything to such thread (injecting an exception from one process to another happens through an STM TQueue, handled from within the monitoring thread), but nonetheless, it’s scary :laughing:

I’d be very surprised there’s no bug in there, so some extra :eyes: (as well as ideas how to test this even more) would be very welcome. Link!

3 Likes

Thanks for those pointers! What those projects achieve is very interesting, though not really aligned with what I propose here. I have no personal interest in targeting the BEAM, however, I do have an interest in having an actor-style framework available for some services I want to implement using Haskell. It’s not even about scalability or availability: web-style handling of individual requests to individual responses with state pushed to some magical “elsewhere” may cover many use-cases, but for some it doesn’t :smiley:

4 Likes

It’s really cool how @NicolasT is creating lots of tickets for the ideas he has for the project, and adding labels such as “good first issue”.

You should check them out: Issues · NicolasT/troupe · GitHub

Looking forward to continue seeing this project flourish, and I’ll be doing the same tickets-for-todos-but-with-visibility-and-clarity for my own WIP projects (read: ghengin :slight_smile:)

2 Likes

Update: thanks to contributions by @tristanC, code landed in main. There are quite likely some bugs in there, and lots of room for improvement, new features and experimentation, so anyone willing to join development is very welcome!

3 Likes

The most interesting use cases for state in memory that can’t be handled by a cache is something like a backend for a live ticket or chat system, where you don’t want to wait for a database call to respond to user.

2 Likes

The Syndicate Actor Model is worth checking out for context.

3 Likes

This, or CapTP, would be a great addition, making actors network-capable (=

2 Likes

Wow. Actor model in Haskell is exactly the thing I’m looking into. Been looking at existing Haskell packages, and also at Elixir. And now I happen to come across this thread (not via web search). What are the odds? :slight_smile:

  • I’m working on a federated web app, with federation based on ActivityPub
  • So the situation is a network of actors, local and remote, an actor framework would be the perfect architecture
  • I’m experimenting with switching to Cap’n Proto / Spritely (which use CapTP mentioned above), but right now the Fediverse is based on ActivityPub so I’ll be going forward with that for a while, maybe a long while
  • So I’m looking for an actor library for local message-passing, which can be extended for network scenarios with a custom protocol
  • Bonus points if there’s some generic network support (e.g. message dispatch) that allows plugging in a custom protocol
  • Even more bonus points if there’s built-in support for per-actor persistent storage

I’m going to try refactoring my code into an actor-style architecture, not sure which actor package to use yet (none seem to be maintained or have good documentation). Maybe just a quick custom one. Giving myself ~5 weeks for this because there’s tons of other stuff to attend to.

Idk if I have much wisdom to contribute here, but I’ll keep an eye on the thread and the repo :slight_smile:

3 Likes

btw, I’m about to start implementing Spritely/OCapN and SAM both. This looks too promising to pass up (8

2 Likes

Let’s join forces! I’m in the middle of refactoring things a bit, so there’s more opportunity of testing using DejaFu. Once that’s in place, I’d like to look into having something alike gen_server implemented.

3 Likes

@NicolasT I am very excited about your effort to bring a proper actor framework to Haskell. We built an event-sourced system in Haskell last year, and the lack of an actor framework was the most painful part.

I’ll rewrite our subscription infrastructure to use Troupe once it’s ready. I’m hoping that it would be easy to integrate it with effect systems. We’re currently using fused-effects, but we’re also looking at migrating to effectful.

1 Like

(is necroing threads ok in this community? I’m never sure. Posting anyway, apologies if anyone minds.)

Hey everyone, I wanted to mention that there is movement on the cloud haskell/distributed process front, and it seems like there could/should be some cross-pollination (or, at least, awareness of similar efforts).
see e.g. Facilitating Cloud Haskell use and development

I do think that it would be totally sensible to have a sort of local-only actor framework (i.e. using STM and local threads to implement actors) as well as a distributed-systems capable framework, as having a local-only actor system can be much simpler than a distributed-process model needing to handle IPC/network comms.

2 Likes

Indeed, distributed-process and friends are being maintained more and more every day.

I would like to point out that executing Cloud Haskell programs on a single node is fully supported by distributed-process, by choosing an in-memory communication backend, most importantly network-transport-inmemory

Happy to hear ideas and collaborate over on GitHub - haskell-distributed/distributed-process: Cloud Haskell core libraries

4 Likes

I think it’s fine. It seems to happen now and again.

1 Like