For simple cases, e.g. implementation of a random function, it suffices to ensure that the state is secured between calls. But, in a database context there are multiple clients active. This means we have to be more precise on the relationship between a co-routine and the client for which it works.
The co-routine concept researched in Monet 5 is the notion of a 'factory', which consists of 'factory plants' at possibly different locations and with different policies to handle requests. Factory management is limited to its owner, which is derived from the module in which it is placed. By default Admin is the owner of all modules.
The factory produces elements for multiple clients. Sharing the factory state or even remote processing is up to the factory owner. They are set through properties for the factory plant.
The default policy is to instantiate one shared plant for each factory. If necessary, the factory can keep track of a client list to differentiate the states. A possible implementation would be:
factory random(seed:int,clientid:int):int; clt:= bat.new(:int,:int); bat.insert(clt,clientid,seed); barrier always:=true; rnd:= algebra.find(clt,clientid); catch rnd; #failed to find client bat.insert(clt,clientid,seed); rnd:= algebra.find(clt,clientid); exit rnd; rnd:= rnd * 125; rnd:= rnd % 32676; algebra.replace(clt,clientid,rnd); yield rnd; redo always; exit always; end random;
The operators to built client aware factories are, factories.getCaller(), which returns a client index, factories.getModule() and factories.getFunction(), which returns the identity of scope enclosed.
To illustrate, the client specific random generator can be shielded using the factory:
factory random(seed:int):int; barrier always:=true; clientid:= factories.getCaller(); yield user.random(seed, clientid); redo always; exit always; end random;