NAME
gk_newenv - create and manipulate shared data
SYNOPSIS
gk_newenv ?-notify? ?-share? ?-client? ?-server? ?-bind? ?-serialize? envName
DESCRIPTION
Environments serve to hold pieces of related information within a single data structure, and optionally share that data between different processes. Environments are hierarchically structured dictionaries. Information in an environment is accessed via a key, which specifies where within the environment information is stored. Because environments are hierarchical, keys serve to encode this hierarchy. Keys use a period (".") as the hierarchy delimeter. For example, the key "local" refers to information at the first level of the hierarchy, whereas the key "local.name" refers to information deeper in the hierarchy.
Environments are created with the gk_newenv command, which specifies a name for the environment. This creates an environment command, similar to Tk's widget commands, which is used to manipulate the environment.
The behavior of environments can also be manipulated by the application program, so that a particular instance of an environment may act radically different from what is described here. The section on customizing environments explains this.
ENVIRONMENT COMMAND
The gk_newenv command creates a new Tcl command whose name is envName. This command may be used to invoke various operations on the environment. It has the following general form:
envName option ?arg arg ...?
The following subcommands are defined for standard environments:
- envName set key value
-
Store information specified by value into the environment at key. value should represent only simple data; use the import subcommand to insert a tree of information. In the case where key does not specify any other subcommand defined for the environment, the keyword set may be omitted.
- envName get key
-
Retrieve the information stored in the environment at key. If key represents a hierarchy of information, it is returned as a keyed list. If the key does not exist in the environment, an empty string is returned. In the case where key does not specify any other subcommand defined for the environment, the keyword get may be omitted.
- envName keys ?basekey?
-
Display the names of the keys directly underneath basekey in the environment. If basekey is omitted, display the names of the keys at the root level of the environment.
- envName delete key
-
Delete the information contained within key. Deleting a key which itself is a parent of other keys deletes all the information in the hierarchy.
- envName exists key
-
Determine if key exists in the environment. Returns 1 if key exists, 0 otherwise.
- envName import basekey data
-
Import a collection of information, specified as the keyed list data Note that data is passed by value, not by reference, which differs from most of the standard commands for manipulating keyed lists.
- envName destroy
-
Destroy the environment, its associated data, and the environment command.
- envName debug
-
Display the contents of the environment on stdout, for debugging purposes.
- envName option args...
-
Store option information in the environment. Essentially, this command allows access to a separate space within the environment designed for storing information about the environment's behavior, as described in the section below on customization. The option space works similarly to the conventional data space. The option subcommand has the following forms:
-
envName option set key value envName option get key envName option delete key envName option keys ?key?
- envName command args...
-
This subcommand is used to modify the behavior of the environment, by manipulating the environment command's subcommands. Its use is described in detail below, in the section on customizing environments.
ENVIRONMENT EVENTS
If the -notify switch is specified when an environment is created with gk_newenv, the environment will generate events whenever its contents are modified. This provides a convenient way for you to model information; changes in the environment (the model) can generate events which will then propagate to change your interface (the view).
Environments will generate three types of events: addEnvInfo (when new information is added to an environment), changeEnvInfo (when existing information in an environment is changed), and deleteEnvInfo (when information in an environment is deleted). In addition to the event type attribute, each of these events also contains an env attribute giving the name of the environment where the change occurred, and a key attribute describing where within the environment the change occurred.
Alternately, events may be generated using a different mechanism, more analogous to Tk's bind command. If -bind is specified rather than -notify, the events will be generated using the notification mechanism described in gk_notifier(n). In that case, the following subcommands are available in the environment:
- envName bind event command
-
Arrange for command to be executed when an event having the type specified in event (e.g. addEnvInfo) is generated. If the string "%K" appears in command, it will be replaced with the key attribute of the event. This command returns a token which can be used to remove the binding.
- envName delbind binding
-
Remove an event binding, where binding is the token returned when the binding was first created.
SHARED ENVIRONMENTS
If the -share switch is specified when an environment is created, the environment will be shared between GroupKit conference processes. The sharing supported by this form of environments does not support any form of concurrency control; it is quite possible for copies of the environment on two different processes to get out of sync. This may in fact not be a bad thing for certain applications, and certainly reduces the overhead and delays inherent in keeping data correctly synchronized.
This version of environments uses the following mechanism for sharing. Whenever a change is made to an environment in any of the conference processes, that change is broadcast to all copies of the environment, via a gk_toAll(n) call. This can lead to race conditions. For example, if process A changes the value X to 3, at the same time process B changes X to 5, the following can occur. Each process will execute the change locally (leaving X at 3 on process A and at 5 on process B), and then send the change to the other process. The end result will be that X has the value 5 on process A, and the value 3 on process B.
Sharing becomes quite useful when combined with notification. If both -share and -notify (or -bind) are specified, events will be generated whenever the environment changes, whether the change was initiated by the local user or a remote process. Applications can take advantage of this by tying their display to events generated by the underlying environment which is used to model the abstract application data.
Shared environments generate one additonal event, envReceived a new user joins an existing GroupKit session, one of the existing users is chosen (via the updateEntrant mechanism) to send a copy of the data already existing in the environment to the newcomer. On the receiving end, this will generate an envReceived event. The application will typically need to traverse the environment, for example to create objects on the display that mirror those in the environment.
CENTRAL SERIALIZED CONCURRENCY CONTROL
A version of shared environments are available for cases where a centralized process is available to manage concurrency control. These environments are therefore not suitable for use in GroupKit conferences, where no such process exists. They are used however by GroupKit's registration system, as well as the rooms based registration client.
The environment must first be created on the centralized process. This environment is created using the -server option.
Environments that connect up to the centralized process are referred to as client environments, and are created using the -client option. After creation, they must then be "attached" to the centralized server process using the following command.
- envName server fd
-
Connect to the centralized server environment, where fd specifies the file descriptor used to send messages to the server process.
Serialized environments work by sending all changes through the centralized process, which then redistributes them to all clients. In this way, changes arrive in the same order on all processes. However, there can be a substantial time delay between when a change is made locally to the environment, and when it takes effect, after the round trip to the centralized server process.
CONFERENCE SERIALIZED CONCURRENCY CONTROL
The final variation on environments is used to provide a serialized concurrency control implementation (as used in the centralized process version described above), but within GroupKit conferences. In this case, one of the users in the conference is chosen as the "central" processes to centralize changes through. This "centralized process" may change as users enter and leave the conference. To use this form of concurrency control, the -serialize option is used when creating the environment. This may also of course be combined with -notify or -bind, but not with -share, -server, or -client.
CUSTOMIZING ENVIRONMENTS
It is possible to customize the behavior of environments, by modifying the subcommands available to the environment. More detail and rationale are described in the paper "When is an object not an object?".
The following environment subcommands are available for customizing environments.
- envName command set cmdname script
-
Specify that script is to be invoked whenever a command of the form envName cmdname args... is executed.
- envName command get cmdname
-
Return the script that is to invoked whenever the subcommand cmdname is executed in the environment. For subcommands not having a Tcl script associated with them (i.e. they are handled by C code), the string "<builtin>" is returned.
- envName command delete cmdname
-
Remove any handler associated with the subcommand cmdname, making the subcommand invalid.
- envName command list
-
Return the list of valid subcommands for the environment.
- envName command rename oldname newname
-
Associate the handler currently attached to oldname with the subcommand specified by newname. The oldname subcommand is still available with the same handler.
SEE ALSO
gk_event(n), gk_notifier(n), gk_runtime(n)
Roseman, M. "When is an object not an object?" Proceedings of the 1995 Tcl Workshop.
AUTHOR
Mark Roseman ([email protected])