[ANN] Runtime Environments released on SqueakMap

Stephen Pair spair at acm.org
Thu Dec 5 03:41:51 UTC 2002


Runtime environments enable variable binding on a per-process basis.
Also, a group of processes can share a common runtime environment.  A
couple example uses for runtime environments are:

	- maintaining a transaction context for a process
	- holding an HttpRequest/HttpResponse pair in a web serving
application
	- keeping user or session information for security purposes 

It's on SqueakMap, or you can download it here:
http://people.advantive.com/~spair/squeak/RuntimeEnvironments.sar

Here are more details from the class comments of RuntimeEnvironment:

Runtime Environments for Squeak
by Stephen Pair <spair at acm.org>

I am a dictionary with an added property that I can inherit associations
from other instances (via the parent inst var).  I am intended to be
used as a set of variable bindings that can be local to a process or
shared among a group of processes.  I am an abstract class and should
never be instantiated.  

Here's how runtime environments work:

You may create a hierarchy of SharedRuntimeEnvironments and directly
manipulate the keys and values of those instances (just as you would any
dictionary).  There is a root SharedRuntimeEnvironment that you may use
to create new children if you like (but you can also create entirely
separate hierarchies).  You can access this root with
"RuntimeEnvironment root".  To force a process to use one of your
SharedRuntimeEnvironments, you write code as follows (note, I only use
'PATH' to highlight the similarity with normal OS environment
variables):

	mySharedRuntimeEnvironment _ RuntimeEnvironment root newChild.
	mySharedRuntimeEnvironment at: #PATH put: '/bin:/usr/bin'.
	Env set: mySharedRuntimeEnvironment.
	Env at: #PATH.  	"-> '/bin:/usr/bin'"
	Env at: #PATH put: ('/usr/local/bin:', (Env at: #PATH)).
	Env at: #PATH.   "-> '/usr/local/bin:/bin:/usr/bin'"
	mySharedRuntimeEnvironment at: #PATH.  "-> '/bin:/usr/bin'"

The first line creates a new shared environment that is a child of the
root environment.  Any variables set in the root environment are also
visible in this new child environment.

The second line sets the variable "PATH" in the shared environment.

The third line uses the "environment accessor" to set the runtime
environment of the active process to our new shared runtime environment.

The fourth line gets the value for the variable "PATH" (which we just
set).

The fifth line in the above example modifies the environment variable
"PATH", but only for the active process.  Before the change is actually
made, the runtime environment is isolated such that changes will not
affect other processes that may be using the same shared environment.
If we wanted to change the variable for all processes using our shared
environment, we would have done that by using
"mySharedRuntimeEnvironment" instead of the environment accessor, "Env".

Here is another example:

	Env at: #PATH put: '/bin'.
	Env clamp: [
		Env at: #PATH put: '/usr/bin'.
		Env at: #PATH. 	"-> '/usr/bin'"
	].
	Env at: #PATH.	"-> '/bin'"

This example shows the use of the #clamp: method to isolate an
environment only for the duration of a block.  After the block finishes
execution, the original environment is restored.

A bit about how it's implemented:

You should only be concerned about creating and maintaining a hierarchy
of SharedRuntimeEnvironments and then assigning those to specific
processes.  You should never directly create an instance of a
LocalRuntimeEnvironment.  In your instances of SharedRuntimeEnvironment,
you will setup your environment variables as you desire.  The changes
you make in your SharedRuntimeEnvironments are visible to all processes
which use that runtime environment.

When a process attempts to modify its environment via the environment
accessor ("Env"), the process will first isolate its environment (by
sending #beIsolated to its environment).  If the environment was a
SharedRuntimeEnvironment, it will do this by creating a new
LocalRuntimeEnvironment whose parent is the SharedRuntimeEnvironment.
If the environment was already a LocalRuntimeEnvironment, then it will
isolate itself (if it is not already isolated) by creating a copy of the
original environment.

When new processes get created, they adopt the environment of their
creating process and flag the environment as being shared (by calling
#beShared).

Using runtime environments, one can create processes or groups of
processes that share a common set of variable bindings accessible via
the environment accessor, "Env".

Some notes about the debugger:

The debugger in Squeak will evaluate code as you step through messages
in a different process than the process actually being debugged.
Obviously, this can present a problem when debugging code that makes use
of runtime environments.  To alleviate this issue, a method,
#inDebuggedEnvironmentDo:, has been added to Debugger.  The #doStep and
#perform:orSendTo: methods of the Debugger have been modified to used
#inDebuggedEnvironmentDo:.  While this does handle a couple of common
issues when debugging processes that make use of runtime environments,
the work is incomplete.  There may be other scenarios where the debugger
can get confused about which runtime environment is in play.




More information about the Squeak-dev mailing list