[Update 3/16/2009: see the post GLASS Beta Update: Cooking with GLASS (Preview) for the latest GLASS preview release. If you update your GemTools Client and GLASS Server as suggested see the Terse Guide to the (new) GLASS Tools for documentation that matches the new tool set].
So you’ve been working with Seaside in Squeak for a little bit and you’ve gotten to the point where you have started to think about persistence. You’ve heard about GLASS, you’ve got 64 bit hardware that’ll run VMWare and you’ve downloaded a copy of the appliance. You’ve clicked on the ‘Run Squeak’ menu item or you’ve executed the Smalltalk expression ‘GsLoginWindow open’ in a Squeak workspace, you’ve got Los Lobos’ ‘Beautiful Maria of My Soul’ queued up and you’re ready to rumba.
We’ll take a quick tour of the tools that will be available with version 2.2.4 to get your Cuban Motion in gear. Even if you’ve been using GLASS for awhile, it’s probably worth skimming this post since there are likely some new capabilities that you’ve been anxiously awaiting.
If you’re new to Squeak and Smalltalk, then you should check out the most excellent Squeak by Example or Steve Wessel’s excellent Squeak Tutorial. If you are new to Seaside, you should check out the Seaside Tutorial from Hasso-Plattner-Institut. If you’re going to do development in GemStone/S, then you should read the articles in GemStone 101.
Here’s a set of links for quick navigation to specific sections:
The first thing you need to do is to establish a GemStone session. With the GemStone/S Login window, you specify the host name (or ip address) where the stone is running, the name of the stone, the host name (or ip address) where you want the gem to run, and the name or port number of netldi. For the Web Edition (i.e., free version), remote gems are not permitted, so the host name for the stone and the host name for the gem will always be the same.
When you press the “Login” button the Squeak image contacts the netldi which launches a gem on the stone’s host. Upon successful launching of the gem, the GemStone/S Transcript window is opened.
The gem creates a log file in the home directory (typically) of the user that owns the gem process (in the appliance that would be /home/glass). If the gem process ever exits unexpectedly, you can check in the log file for error messages.
The most common reason for a gem to exit unexpectedly is that it ran out of memory. If the gem runs out of memory, a fairly detailed report is dumped to the gem log. If there are no errors when the gem exits it will delete it’s log file. If you do run out of memory, you can bump up the size of the GEM_TEMPOBJ_CACHE_SIZE in the gem.conf (on the appliance it’s found in /opt/gemstone/product/seaside/data).
The GemStone/S Transcript window is the control point for interacting with your GemStone session. For all of the GemStone tools, we are using Squeak as a windowing client. You want to remember that there is no interesting Smalltalk state being kept in your Squeak image, other than what is necessary for displaying the windows.
All of the GemStone tool windows have bland grey color and a “G/S[<GCI#>]” in the title bar to remind you that you’re in a GemStone window. You can open multiple sessions (gems) from a single Squeak image, so the GCI# helps you tell which session the window is operating against. Since the GCI library is not thread safe (i.e., only a single GCI call may be made at any one time), running multiple sessions from a single Squeak image is of limited utility.
The row of buttons across the top of window, give you quick access to the most commonly used windows and functions. Each window/function is covered in its own section:
The text pane in the GemStone/S Transcript window is actually a workspace and not a transcript. This window is slated to be reimplemented in OmniBrowser and we’ll fix the name then:). When you do an accept in this window, the text is stored in a class variable on the Squeak-side, so the text can be preserved across session boundaries. This is the one piece of state that would make it worth saving your Squeak image.
While we’re talking about image saving, it used to be that when you saved the Squeak image, all GemStone sessions were unilateraly destroyed rendering all of your GemStone windows inoperable. With the tools being released in conjunction with version 2.2.4, it is safe to save your Squeak image with GemStone windows open. When you restart a saved image, all of the open GemStone windows will be closed.
When you close the GemStone/S Transcript window (or press the Logout button), the GemStone session will be terminated (i.e., the gem process will exit) and all of the GemStone windows in the Squeak image associated with the session will be closed.
Back in December, while I was watching Avi write the Monticello tools in OmniBrowser, I saw him use some keyboard shortcuts that weren’t on the text pane menu. He was browsing classes and bringing up senders and implementors windows with a couple of key presses – things that I had been struggling to do without shortcuts.
In most GUIs, a program’s keyboard shortcuts are discoverable by browsing the program’s menus – the shortcut is indicated in the menu choice.
Without going into the pros and cons, I decided to keep the menus short and follow the Squeak/OmniBrowser example. The following keyboard shortcuts are supported in all of the GemStone text panes whether they show up in a menu or not:
- CTL-b browse selected class
- CTL-N references for selected class
- CTL-n senders of selected selector
- CTL-m implementors of selected selector
- CTL-E methods containing selected string
- CTL-i inspect it
- CTL-p print it
- CTL-d do it
In workspaces, the evaluation context for CTL-i, CTL-p, and CTL-d, is not defined, which means that you can’t use ‘self’ in workspace expressions. In code browsers the evaluation context is the selected class (‘self’ is the class), in debuggers the evaluation context is the message receiver, and in inspectors the evaluation context is the inspected object (you have to select a field in the inspector to set the inspected object).
I am going to write separate post to cover Monticello in GLASS. Suffice it to say that OmniBrowser-based Monticello tools closely parallel their Morphic-based cousins with the exception of a couple of functions that were not used a whole lot. If you find what you consider an important piece of functionality missing, by all means let me know via a comment on this blog, or join the news group described in the Bug Reports section.
For those of you who have been using the Morhpic-based Monticello tools. You will be happy to know that the arcane rigamarole that you used to have to go through after loading a package is no longer necessary. Changes to the code in a package will cause the package to be marked dirty, however, you may have to refresh a window to see the changes.
I have not implemented a window to window update mechanism, yet, so changes made in one window will not automatically show up in another window. Getting window updates to propogate is high on my priority list.
When you press the Browse… button, you are prompted for a ‘Class name fragment’ (no need to worry about capitalization or including wildcard characters). If the fragment resolves to a single class, a System Browser is opened on that class. If the fragment resolves to multiple classes, you are given a list of classes from which to choose your desired class.
From the System Browser, you can navigate to the full complement of windows available in OB-Standard.
You might notice that in the class category pane, there is no ‘add category’ menu item available. GemStone manages it’s classes slightly differently than Squeak and the Class categories are derived from the classes. So when you create a class, you create the new category along with the class.
When you press the Find Method… button you are prompted for a ‘method fragment’ (no need to worry about capitalization or wildcard characters and multi-keyword selector fragments like ‘at:put’ are fine). If the fragment resolves to a single selector, then an Implementors window is opened, otherwise you are prompted to choose the selector of interest from a list.
The Implementors, Senders, and Variables windows are chasing browsers. The upper right pane contains a list of the messages sent by the method selected in the upper left pane. If you were to click lastValue in the upper right pane, you’d get a scroll bar below the selection lists, the left pane would be replaced by the messages pane and the upper tight pane would contain a list of implementors of #lastValue. You can scroll back to the left to see the original implementors left, or continue walking panes to the right. Chasing browsers are a little disconcerting to use, but once you realize how much the window clutter is reduced by using them, you will grow to like them.
Occasionally, when you accept a method in the Implementors, Senders, and Variables windows, the method text will appear to revert back to it’s original value. If you reselect the method, you will see that the source you accepted has actually been saved. There are a handful of these update bugs that I will be hunting down and eradicating as time goes by.
The Test Runner is one of the last remaing Morphic windows in the GemStone tool set. When you press the Test Runner button be prepared to wait a bit while a ton of data is transferred from the gem to the Squeak image. Updating after making a selection can take a bit as well, but I’d rather have a slow Test Runner window than none at all.
Not all of the functions in the Test Runner are functional for the GemStone tools, but ‘Run Selected’ works and if you get errors or test failures, clicking on the failure will bring up a GemStone debugger. Note also that ‘run test’ menu items can be found in the category, class, protocol and method panes of the code browsers.
When you look at the debugger you immediately notice that the receiver and context inspector panes are missing! Until very recently it was difficult to get OmniBrowser to lay out a window configured like a traditional debugger. Lukas has been busy working on OB-Tools which implements a number of the Squeak windows using OmniBrowser and I think he may have a version of the debugger with integrated inspectors. I last merged with OB-Tools-lr.13 and Lukas is up to Ob-Tools-lr.19. Add one more item to my todo list.
To get around the lack of integrated inspectors, I added an ‘inspect context’ button that brings up an inspector that gives you combined view of the context and the receiver. The context inspector is slaved to the debugger, so that as you select different contexts the inspector updates its view to reflect the state of the selected context. I like the extra screen real estate afforded by the context inspector and dislike the fact that I am a couple of clicks farther away from seeing important information.
To facilitate Bug Reports, I’ve added a ‘copy stack’ menu that prints up a stack report including receiver and context info for each stack element.
GemStone/S supports breakpoints, so it isn’t always necessary to edit a method to get the debugger to stop at an interesting point. The definition pane menu in the code browsers and debugger has a ‘set breakpoint’ item that will set a breakpoint at the selected point in a method. For a method that has a breakpoint set, an additional menu item, ‘clear method breakpoints’, shows up and allows you to clear all of the breakpoints in the selected method. If a breakpoint is set on any method in the system, a ‘clear ALL breakpoints’ method shows up on all of the definition pane menus and will clear all the breakpoints in your session when selected.
A breakpoint browser is on the drawing board that will allow for the individual control of breakpoints, including disable/enable selected breakpoints.
Breakpoints are session-based and are associated with a particular instance of a method. If the method changes by either code changes on your part or the method is changed via an update via a commit or abort, then the previously set breakpoints aren’t active on the new instance of the method.
Like the Implementors, Senders and Variables windows, the Inspector window is a chasing window. When you click on a field in the upper left inspector pane, the inspector for the object associated with the selection is shown in the upper right pane. The context for bottom workspace pane is derived from the selected object (not the selected field). Selecting a field in the upper right pane will bring up the scroll bar for the selection lists, sliding the upper right pane to the left, and showing the object inspector for the newly selected field in the upper right pane.
The example below happens to be a context inspector associated with the debugger window in the Debugger example.
Selecting the currentRequest field in the above example, shows an inspector on the instance of WARequest in the upper right pane. A field is selected for the instance of WAExpirySession in the upper left pane so a CTL-p in the bottom pane on escapeContinuation will be evaluated in the context of the WAExpirySession instance.
If you type an expression in the bottom pane and hit CTL-s, the value of the selected field will be set to the result of the expression (Liliana, you should be happy now:).
The Abort and Commit buttons in the GemStone/S Transcript window allow you to manually abort or commit your work.
When you press the Commit button it is the moral equivalent of saving your image in Squeak. The Abort button is the moral equivalent of quitting your Squeak image and restarting from your latest saved copy.
When you abort or commit, you are updated to the latest view of the repository. With an abort, all changes to persistent objects are discarded before the update. With a commit, your changes to persistent objects are incorporated into the latest view of the repository. For more information of transactions, take a look at the posts in GemStone 101.
Inadvertant use of the Abort button can be disastrous, so you are prompted before the abort is performed.
As discussed in GemStone 101: Transaction Conflicts, if during your interactive session you have executed code that has made changes to an object that was also changed by another session since your last abort, you will get a transaction conflict if you attempt to commit. If the commit fails due to transaction conflicts, you will see the following notification:
No matter which option you choose, you will ultimately have to abort your session before being allowed to commit again. Transaction conflicts do not happen very often during development, especially if you are working by yourself;).
In a group, a transaction conflict could occur if two developers made changes to the same class at the same time. For group development it makes a lot of sense to give each developer their own appliance (or userID) and use Monticello to share your code.
If you are doing development against a stone where the Seaside application is being hit by other users or processes (i.e., siege or WAPT) and you are actively updating shared data structures, you could very easily hit a transaction conflict.
Choosing to inspect transaction conflicts will bring up an inspector on the transacation conflicts Dictionary. Take a look at the comment in System class>>transactionConflicts for more details on the information contained in the Dictionary.
To create the above transaction conflict, I opened two GemStone/S Transcript windows, evaluated the expression ‘UserGlobals at:#Shared_TEST put: Object new’ in one workspace and pressed Commit button. This defined a new association in the UserGlobals SymbolDictionary. I pressed the Abort button in the other session’s transcript window and evaluated the same expression it it’s workspace and pressed the Commit button. Then in original transcript window (without pressing the Abort button first), I evaluated the expression again and pressed the Commit button, which gave me the transaction conflict. Knowing which object(s) are involved in the conflict should give you a pretty good clue as to where the problem might be located.
I am afraid that I may have broken the functionality of the Auto commit checkbox in the GemStone/S Transcript windows when I moved the browsers and Monticello to OmniBrowser. Given the frequency with which I press the Commit button, I will probably fix this feature in a future release, if noone else beats me to it:).
If you just loaded some new code into the GemStone repository, or finished doing a bit of development, the easiest way to test out the new code is launch Hyper directly from your session, so that you can bring up the Debugger, if you encounter a problem.
The Hyper button prompts for a port number and launches a Hyper instance that is listening on the specified port number. You can then hit that port from your browser using a host name or ip address (i.e., http://172.16.172.134:9765/seaside or http://glass:9765/seaside or http://localhost:9765/seaside).
In older versions of GLASS, the Hyper-based web server required an exact match between the name of the host that you used to launch Hyper and the name of the host in the URL, which caused some unnecessary difficulties in connecting to the Hyper server.
When you launch Hyper, we block the UI process in Squeak. To interrupt the Hyper thread, you can hit Alt-.. Rember that for every HTTP request that comes in, the gem performs an abort, processes the request, then performs a commit. If you were trying to write code while this was going on, you’d easily lose chunks of work without warning.
If you want to do development and handle debuggable HTTP requests at the same time, the best solution is to fire off one Squeak image that is dedicated to running Hyper and use a second Squeak image to do development. When you’re done writing a batch of code, you can commit and the gem running Hyper will see the changes after the next request comes in.
If you hit a problem, you can use the debugger in the Hyper image to figure things out, just remember to commit your changes in the Hyper image before proceeding or restarting the Hyper process. Back in your development image, you’ll want to do an abort to pick up the changes that you made in the Hyper image. Breakpoints are session-specific, so you will need to set any breakpoints in your Hyper image, before launching Hyper.
If you find yourself trying to debug a problem that only shows up in FastCGI, you can arrange to start one or more Squeak images running FastCGI. For example, if you are using the appliance you could stop the threee gems that are servicing FastCGI requests and start three Squeak images to serve the FastCGI requests. Execute ‘FSSeasideHandler startUp: 9001′ in a GemStone workspace in the first image, ‘FSSeasideHandler startUp: 9002′ in the second, and ‘FSSeasideHandler startUp: 9003′ in the third. Alternatively, we’ve defined an Apache virtual host for each FastCGI port, so you can start just one Squeak image on FastCGI port 9001 (‘FSSeasideHandler startUp: 9001′) and then hit http://glass:8081/seaside with your browser. Ports 8081, 8082, and 8083 bypass the Apache load balancer and route HTTP requests directly to the FastCGI ports 9001, 9002, or 9003 respectively.
When the Logout button is pressed, the session is terminated and all windows associated with that session are closed, including the GemStone/S Transcript window.
With release of GemStone/S 64 version 2.2.4, the tools are finally of Beta quality. I’ve mentioned a couple of the known problems in this post, but my philosophy on bug reports is that you can’t have too many of them – don’t assume that we’ve seen the obvious problems, if you think it is a bug let us know.
To report bugs, sign up for our GLASS Beta mailing list and send a message to the list detailing the problem you’ve seen.
Even if you don’t have a bug report, I encourage to sign up for the GLASS mailing list. Seaside specific questions should still be directed to the Seaside mailing list. GemStone-specific questions can also be routed to the GemStone/S customer forum, most of our customers hang out there and are always willing to help folks that are new to GemStone/S.