Skip to content

Gren's concurrency story #65

Open
Open
@robinheghan

Description

@robinheghan

The concurrency story of Gren is incomplete. Finalizing the concurrency design will be important in order to reduce churn as new platforms and APIs are added to the mix.

Today, several concepts make up the concurrency story:

  • Tasks
  • Commands
  • Subscriptions
  • Programs
  • Effect modules
  • The Process API
  • The Platform API

Let's spend a little time explaining each of these before talking about how it can improve.

Tasks

A Task represents an asynchronous effect. You can chain tasks together, forming a series of steps that will be executed at some later time. Creating a task doesn't do anything, it must be passed on to the runtime in order for it to run.

A Task can either succeed or fail, and the user is free to describe what should happen in either case.

Commands

In order to execute a Task, you will need to command the runtime to execute it. Commands cannot be chained, they represent a complete instruction to the runtime.

A command has a reference to a message which will be sent back to the application's update function once the command has completed.

Subscriptions

Sometimes, the application want's to receive messages without necessarily having sent a command first. A Subscription represents the application's willingness to receive such events.

This might be stuff like receiving a notification that system memory is low, or that a message is waiting on a socket.

This is in contrast to commands, which represents a message the application sends out, with the potential to receive one single message in the future (the answer).

Programs

A program is a stateful process that can send commands and listen on subscriptions. Defining a program means defining the functions that should be called upon initialisation, when messages are received, and how to send commands.

There is only one program. However, this program can communicate with other processes through commands and subscriptions.

Effect modules

An effect module is a single stateful process that can send commands to itself and to the program. There can only be one instance of an effect module, and it cannot listen to subscriptions. It can however provide a subscription, and it defines the kind of commands it can receive.

Effect modules can be initialised asynchronously. This is in contrast to programs which must be initialised synchronously, but can provide a command to run in the future.

Effect modules can only be created in core packages.

The program doesn't need to specify an address to talk to an effect module, the runtime will figure it out based on the command sent.

The Process API

This API is unfinished. Its main useful function is sleep which returns a task that, when executed, waits for a certain amount of time.

The documentation outlines future plans for how processes might work, but otherwise contains fairly little.

The Platform API

This API contains the basic building blocks of any program. It defines the process and task types, and a basic way to create a program. It also contains a router, which effect modules use to send messages to either itself, or to the running program.

Thinking ahead

I tend to think of programs and effect modules of specialised implementations of stateful processes. Such processes can be a very useful thing for application and package developers to define. Examples range from connection pools, caches, batching operations etc.

I think that the ideas listed in the Processmodule, letting you spawn a process and be handed it's ID, to be used for sending it messages or simply killing it, to be a good idea.

I also imagine that if such a thing was possible, that it could replace effect modules.

Effect modules does have a benefit in that you don't need an ID in order to send it messages, meaning less boilerplate. However, if you were required to have an ID in order to perform some side effect, then you would essentially have a very powerful permission system.

Today, APIs like random, http and time are represented by effect modules. Implementing those as processes would mean that the application would have to spawn them before the application could be initialised. It would also have to keep track of the IDs to these processes, and pass those around to the parts of the code which required such functionality. The payback for this increased amount of code, is complete control over what parts of your code, third party or not, is allowed to perform a side effect.

If implemented, this would also replace programs. A program is just a process, in any platform.

In the future, processes could be spread across different WebWorkers in order to utilise parallelism.

Metadata

Metadata

Assignees

No one assigned

    Labels

    explorationa description of how something could potentially work

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions