LITHIUM
LITHIUM is the dispatcher. From the perspective of an application programmer, it's the core of an ARGON system. LITHIUM is what actually invokes their code.
Entities are stored in TUNGSTEN; both their code and their current state. The code within an entity has entry points, known as handlers; the list of handlers is stored within the entity's state in TUNGSTEN. Every handler has an ID, and some metadata. Part of this metadata is for consumption by LITHIUM, and explains how to invoke the handler; the rest of the metadata is for consumption by the system component that asks LITHIUM to invoke the handler - generally MERCURY for handlers that provide services to remote clients over the network, CAESIUM for handlers that are periodically invoked according to a schedule, WOLFRAM for distributed processing within the cluster, FLUORINE for providing legacy protocols, NEON for activity from user-interaction hardware, or other optional system components that provide interfaces to special hardware such as printers.
LITHIUM is given a request to invoke a specific handler in a specific entity, along with information from the requester about the HELIUM resource limits and scheduling priority to impose, and any parameters to be passed to the handler. It then proceeds to consult the metadata concerning that handler to decide how to handle it.
Firstly, the entity we are being asked to invoke a handler of may be in a volume which this node does not carry. This can be realised by simply examining the entity ID; TUNGSTEN need not be consulted. If this is the case, we consider the set of nodes that carry that volume to be the set of nodes eligible to invoke the handler, and skip the next step.
Secondly, the handler may be bound to a specific set of nodes (often, this will be applied to all handlers in an entity, but in general, each handler could have a different binding set).
This has given us a set of nodes which are eligible to run the handler. If the current node is not within that set, then the least heavily loaded node in that set that is accessible from this node should be contacted via WOLFRAM and the LITHIUM instance there asked to invoke the handler. If this fails for any reason, the next least heavily loaded applicable node is tried; if none of them will take on the job, then LITHIUM has to return an error. The requester may opt to handle its own redirection, in which case, if the handler cannot be invoked on the current node, then a list of nodes will instead be returned rather than LITHIUM attempting to forward it itself. MERCURY will use this option, since rather than proxy a request to another node then have to proxy the reply, it is more efficient to simply return a redirect to the caller and have them handle it.
Next, LITHIUM has to decide how to invoke the handler. Mainly, this boils down to consulting the metadata to see which programming language the handler is written in. The expected answer is CHROME, the native high-level language of ARGON, but this is not necessarily the case. I don't expect to be providing the ability to write handlers in low-level HYDROGEN code, since that exists outside of the memory protection umbrella of CHROME, but perhaps this may change - handlers may be written as HYDROGEN code that gets executed within a HYDROGEN virtual machine with a hypercall interface to the rest of the system, to allow distribution of code in 'compiled' form - or if people really want to write high-level code in HYDROGEN. But they'd have to be mad to do that. Surely?
As well as CHROME, I'm interested in supporting existing languages. There are obvious commercial advantages in doing so; ARGON might be useful as a Java application server, or to host Python or Scheme. So LITHIUM must consult the handler metadata to find out what programming language it uses, then examine a table of available programming language systems. Exactly how the source code for a handler is stored in TUNGSTEN is the business of the programming language, so the programming handler is invoked, within a HELIUM context created for the purpose of this invocation (with appropriate resource limits and scheduling priorities set up), and given the details of the invocation.
Security is the responsibility of the programming language module. The handler may only access resources under the guise of the entity, for access control and auditing purposes. So the handler is given access to TUNGSTEN, but it can only access state within its own entity. It is given access to the MERCURY client, but it can only issue requests with its own entity ID as the originator. It is given access to WOLFRAM, but only the ability to access global state such as the list of accessible nodes, and the ability to invoke handlers within the same entity on those nodes. It is given access to HELIUM, but only to access state of the context it is running in, and without the option of raising its own resource consumption limits or increasing its scheduling priority.
In particular, since multiple handlers, and other system components, will all be running at once on the same entity, memory protection is paramount. Either the programming language must certify that code written within it cannot obtain a reference to an object other than objects it creates itself or are given references to by other parts of the system, or it must be run within some kind of restricted virtual machine and access the rest of the system via a hypercall interface.