Session Manager Service
The Session Manager Service is a graphical-based service used in EiffelStudio to persist and retrieve data between multiple sessions of EiffelStudio. The session manager (SESSION_MANAGER_S) provides access to state persisted sessions in four flavors; Environment, Per-Window, Per-Project and finally Per-Window/Per-Project. The fine grained control of session states proffers a mechanism needed to restore EiffelStudio as it was left as well as restore a project to exactly how it was left when it was closed.
Session data replaces the need to define (hidden) preferences in order to persist data between running sessions of EiffelStudio, making the process of storing session data much simpler.
Contents
Preferences Vs. Session Data
The session manager service is very simple to use and supports arbitrary data types so you may want to jump right in an use it instead of the defining a configurable preference. Session data and preference data have different roles so it is important you choose the right method of data persistence for the task you are trying to perform.
Both session data and preference data are persisted between opened and closed sessions of EiffelStudio, which is the extent at which the are akin. Session data will never been seen by the user whereas preference data can be viewed and modified from within the EiffelStudio IDE. It would not be wise to store a discardable dialog prompt's discarded state in a session because the user may want to revert back to view the dialog prompt at a later time - this is a clear case for a preference. On the other end of the scale, storing a tool's tool bar toggle button's selected state would be ideal to store as session data instead of preference data. That said, storing a toggle button's state in session data might not applicable for the task it's to perform. Note the reference to a tool's tool bar button. A tool is general self-contained and should not affect the behavior of other parts of EiffelStudio. Tool bar buttons on the main tool bar, which actually affect EiffelStudio as a global entity generally should not use a session but a preference instead. The exception to this rule is if data needs to be persisted on a per-window or per-project level.
Sessions and Aggregated Sessions
Sessions come in four flavors, with each session being distinct. This could be a hassle for anyone wishing to access multiple session data, such as both the environment as well as project-level data. Fortunately most of the session data objects are aggregated to support retrieval of session data for a higher, wider scoped session. The only session that is no aggregated is the environment session as there is no wider scope that the EiffelStudio environment itself, which encompasses all opened windows.
Here is a brief run through of the level of data that can be read by a type of session:
- A environment-level session will only provide session data exposed in the environment session.
- A project-level session will provide session data exposed in the environment session.
- A window-level session will provide session data exposed in the environment session.
- A project and window level session will provide session data exposed in the window session and then session data exposed in the environment session.
Using Sessions
Session Data Identifiers
To use a session object to persist and retrieve session data clients will need to define a session data id. A session data id is a string constant used to identify chunks of session data in the session object so it can be indexed for storage and retrieval between sessions of EiffelStudio. Strings are inherently problematic for uniqueness and UUID are limiting in readability as well as prohibiting static access to a session data id, if required. As such, string id's were chosen to index session data with a recommended namespacing convention to ensure uniqueness.
Session Data Identifier Recommendations
There is not absolute rules to declaring a session data identifier except that is must be a non-empty attached string object. However to ensure uniqueness the following rules should be adhered to:
And id should...
- Be defined as a namespace using periods (.) to split segments, contains no whitespace and using a reversed company or personal URL domain prefix. For instance all Eiffel Software session data id's start com.eiffel.
- Include a context, such as the name of a tool or region inside EiffelStudio.
- End with a brief description of the session data.
- Predominantly use alphabetically characters.
As an example, for an Eiffel Software tool (the Error List) perserving the expand error description toggle button state:
com.eiffel.error_list.expand_errors
The session data id is split into; reversed URL domain: com.eiffel
, tool name: error_list
and a session data description: expand_errors
.
Retrieving Sessions
In order to work with a session, represented by a SESSION_I interface, you will need to query for the session manager service. This can be done using a service consumer or via accessible service provider.
There are only two function exposed on the session manager service for retrieving a session, and are used depending on what type of session needed to be retrieved; retrieve
and retrieve_per_window
. retrieve
will retrieve an environment or project-level sessions where as retrieve_per_window
is used to retrieve window or project/window-level sessions. retrieve_per_window
requires an additional argument specifying the window to retrieve a session for.
The following code retrieves a session for the environment:
environment_session: SESSION_I -- Retrieve the environment (IDE) session. local l_sm: SERVICE_CONSUMER [SESSION_MANAGER_S] do create l_consumer if l_sm.is_service_available then Result := l_sm.service.retrieve (False) end end
For window-level sessions, retrieval is even simpler. In order to retrieve a window-level session using retrieve_per_window
a client needs to have access to a valid (attached and non-recycled) EB_DEVELOPMENT_WINDOW object. EB_DEVELOPMENT_WINDOW actually exposes session_data
to clients, which is the respective window-level session data.
When retrieving project-level sessions there is no need for a attached project object to be supplied, the reason is two fold: (1) EiffelStudio currently only supports a single project loaded at any one time and (2) it may be necessary to retrieve a project-level session before the project is loaded. The internals of a project session will ensure that once a project is loaded the session data is set and the appropriate events are fired.
Note: Although it is possible to retrieve a project-level session before a project is loaded, the session data will not be respective of the last persisted project. Until a project is loaded there is no way for the session manager to determine which project session data should be retrieved for. Once a project is loaded any project-level sessions will be updated with the loaded project session data. Clients can receive notification of this by subscribing to the value changed events.
For tool developers, ES_DOCKABLE_TOOL_WINDOW already exposes access to both environment and window-level session objects via session_data
and window_session_data
respectively.
Storing Session
Sessions can be stored either on a per-session basis or the session manager service can store all sessions. The session manager service (SESSION_MANAGER_S) interface exposes store
, for storing a independent session object, or store_all
for storing all applicable sessions.
Session storage is optimized only to store what needs to be stored. A session object is not stored if no changes to it's session data have been made (this can be observed by querying is_dirty
on the session object's interface SESSION_I.) Even calling store
explicitly, passing an unmodified session objects, will bypass storage. Session storage is also skipped if a session is never retrieved from the session manager, which is only applicable in the case of using store_all
as store
requires a session object.
Note: Session storage optimizations are only applicable to the default implementation of the session manager service. If the session manager service is replaced by a third-party service then the optimizations may not be performed.
EiffelStudio actually perform storage of all session when any development IDE window is closed, so there is no need to explicitly store any session, unless a cases presents itself. In such an exception case, it is up to you do decided when a session should be persisted. Any code that explicit session storage should be designed with a slower session manager in mind as other editions, even first-party future editions, may alter the persistence mechanism in any given release. A potential alternative mechanism would be persisting session data to online storage, which varies greatly in performance.
Determining the Type of Session
Store Session Data
Session data, for the most part, can be scalar data or arbitrary objects but there are objects that will cause problems if they are passed as or are referenced by any session data.
What Not to Store
Expanded non-basic types will cause problems with the 6.2 development branch because of the storage mechanism used. The solution to this is currently to enclose an expanded value in a CELL object. This boxing is not requires for the basic built-in types because the storage mechanism is aware of these types and performs the boxing and unboxing as necessary.
Any reference type can by used as session data but the object should not retain any reference to any internal objects of EiffelStudio or any of it's referenced libraries, such as EiffelVision2. The current storage mechanism will try to resurrect these objects causing problems when the object in turn tries to function or perform operations using those resurrected object(s). The problem arises as the objects may not actually be tied to the environment itself and so the session and the running EiffelStudio internal states are out of sync. As a remedy for a first level of protection all session data objects have to implement SESSION_DATA_I. Any attributes of the session data object do not have to implement SESSION_DATA_I as it is likely the session data object will contain reference to rudimentary structures, so this restriction cannot be imposed.
Session data objects should also no reference any pointers from either external or internal resources. Resurrected pointers will likely point to an illegal, uninitialized memory location causing a segmentation violation when used.