Last updated at 3:07 pm UTC on 15 December 2007
Magma provides very suitable database support to a Seaside web application. This page describes a new approach for Seaside version 2.8 which supercedes Magma seaside. See Also: Magma SeasideHelper ToDo List Tutorial
The Magma repository on SqueakSource includes a package Magma seasideHelper. This package may be installed after installing Magma, Seaside, and Seaside28Jetsam, to provide comprehensive support for Seaside applications which use a Magma repository as one option for persistence.
To install magma and seaside into a base 3.10 image:
Installer squeaksource project: 'Installer'; install: 'Installer-Core'.
install: 'Magma seasideHelper';
To use Magma with a Seaside application add WAMagmaConfiguration to the list of configuration 'ancestors'.
This enables the #magma group of configuration parameters. There is a selector for choosing the database helper class which provides session management. The simplest and most transparent option WAMagmaSoloAuto is selected by default. The configuration application provides detailed comments as to the functionality of each helper class.
The local database directory #location is automatically set so that it saves the data in 'magma-yourapp' directory for the 'yourapp' entry point. This default ensures that separate applications will not step on each others data.
Magma may be used directly with other seaside technologies, such as Comet or GLORP. In particular Magma seasideHelper does not require any specialized subclass of WASession to be written.
This is accomplished through the WASessionHelper framework (a part of Seaside28Jetsam). The chosen Magma Helper is accessible via WASession-#magma
Typically the magma helper is available in your code via:
self session magma
Communication with Magma occurs through database sessions. Each Seaside session has its own Magma Helper which will internally create its own connection to the Magma repository, known as a MagmaSession.
Magma helpers provide a range of session management schemes:
- single - WAMagma
- shared - WAMagmaSolo, WAMagmaSoloAuto
- pooled - WAMagmaPooled
- mock - WAMockMagma
More Session Management
A second magma configuration option is available to support combinations of session management types.
e.g. a shared session for read only access or login validation.
If you wish to use a second type of session management, or a second database, in parallel then add WAMagmaConfiguration2nd to the list of configuration 'ancestors'. The second session is available via WASession-#magma2
Typically the second magma helper is available in your code via:
self session magma2
Regardless of which type of helper or connection is used (local or remote), the Seaside application code remains exactly the same. All access to the data is transparent; e.g., via normal method sends. Each session's view of the data is refreshed at each transaction boundary, with optimistic locking to ensure consistency.
Some helpers (e.g. WAMagmaSoloAuto) provide automatic #commit transactions as part of the Seaside request-response life-cycle. This means that seaside application code need not be aware of the presence of the database at all.
Accessing Your Data
Data for your Seaside application, or any sub-domain of your application is accessed via a "root object" (one of many). Once a root object is obtained, it may be used as any normal object and data will be reified from the database as needed. If an obtained object is a subclass of MagmaCollection then you can use Magma Queries to obtain sub-sets of large datasets.
Your "root objects" are accessible without reference to their place in the actual database structure. Clients are encouraged to always use the following idiom to obtain models from the database, since the model classes themselves know where in the database structure they are to be found.
self session magma rootAs: MyModelClass.
This scheme allows several applications or sub-domains to be layered upon a single database. Each model class can nominate the position of its own root object (see class methods #getVirtualRootIn: #setVirtualRootTo:in: etc.) in the main database. This also allows the database to be re-organised by changing model classes only. The seaside application domain views are decoupled from the macro-structure of the database via this #rootAs: idiom.
The actual database root which is effectively invisible to your application, is automatically initialized to an instance of WADictionaryRoot.
When defining your sub-domain root objects, create concrete subclasses of general purpose classes (such as Object, Dictionaries, or MagmaCollections) Specialize these model classes so that they know where in the database they are located, this also means that they know how to initialize themselves via their #initialize method. (see class methods #getVirtualRootIn: #setVirtualRootTo:in: etc)
The #initialize method provides a natural place for subclasses of MagmaCollection to initialize their indexes. Specialized domain specific query methods can also be added to the class. If the query-reader is cached in an instance variable, this query-reader will itself become persisted in the database, and the server can provide an optimized pre-calculated response.
Note: Subclasses of Dictionary (and hence WADictionaryRoot) may not have additional instVars due to a known limitation of Magma.
Larger systems may utilize a remote connection to the Magma repository running in a separate image. This should scale to a significantly larger user base, particularly in the context of multiple Seaside images (each handling a finite number of Seaside sessions), by dividing the heavy Magma-client burden across multiple images, threads, machines. The lightly-taxed Magma-server will not starve so long for requests and, under maximum throughput conditions, always have a few requests queued and ready.
Under this configuration, each MagmaSession accesses the repository over TCP. To this end only the host-name and port need be supplied.
Note, when using a remote connection, the remote repository must be opened and started separately, for more information see Getting started with Magma.
Magma Server transactions are logged in such a way as to enable secondary read-only slave servers to be kept up to date, and so the load of read only queries can be shared among several remote Magma servers.
Server Managed Preferences
WAServerManagedPreferences is intended to allow a number of seaside servers to be given some of their application's preferences from a central persistent store. It is implemented as a module, to be as self contained as possible.
This module allows a Seaside server application to pick up settings and preferences from the Magma server. Whenever a new Seaside session is started, and the actual root is read for the first time, the helper's #onFirstRead: method is called. The default behaviour calls self rootAs: WAServerManagedPreferences'.
If the expire time has been reached then any persisted preferences are read and the current application's preferences are updated with the values that it contains. The values returned are each sent #value before being applied.
This would allow #location to return a specialized version of MagmaRemoteLocation which, when sent #value, evaluates the selection of a remote server based upon the client's identity.
Magma SeasideHelper ToDo List Tutorial
Contact Keith Hodges or the Magma mailing list for assistance.