Archive Page 2

An Alarming Requirement

A little while back, one of my colleagues at TAF came to me with an interesting challenge. He had been assigned the task of making a production application raise a visual and audible alarm in response to invalid actions on the part of the user. It doesn’t seem like that hard a problem until one realizes that our applications are actually running in XWindows sessions on an AIX server. This means that the running application thinks that its environment is the AIX server, and it knows nothing about the machine actually displaying the user interface.

In the past, this sort of requirement was handled by using a Programmable Logic Controller (PLC), and running conduits and wires from the PLC to the location where the output was wanted. This gets the job done, but it’s expensive to install and move, and requires a lot of lead time if a change in location is needed. On top of that, one also has to involved the services of a PLC programmer, and it may even require the acquisition of an additional PLC if a free port is unavailable on one of the existing alarm-capable PLCs. We needed to come up with a cheaper, more flexible solution.

At first, it was a bit of a head scratcher, but, as it turns out, an application running under XWindows can get one vital piece of information about its environment: the IP address of the machine actually providing the display. In VA Smalltalk, the command “‘DISPLAY’ abtScanEnv” will give you a response of the form ‘xxx.xxx.xxx.xxx:0.0’ where anything up to the colon (:) is a host name or IP address, and anything after is the XWindows display number. In our case, we’re only concerned with the host name or IP address. If the XWindows display is actually running on the same machine, the host name will be blank, and you’ll get back something like “:0.0”.

Knowing how to get to the physical computer, we can now think about what to do there. While I have complete control over how the client machines are loaded, it’s generally preferable to keep the installed software to a minimum. Everything I needed to do could be done from a UNIX shell prompt, so using some shell scripts seemed the best answer. Modern Linux implementations make it easy to set up TCP daemons using xinetd, so I set up a listener on a TCP port that invoked a simple script.

My Smalltalk program opens the port on the client machine using Totally Objects SocketSet, writes a value to the port, and closes it again. On the client machine, the script reads a line of input from STDIN, and uses that input to invoke an appropriate alarm script. You could do the same thing with VA Smalltalk’s socket support, but if you value your time at all you’ll quickly come to appreciate the benefit of Totally Objects’ product.

This has been working quite well, but a new curve was thrown at me recently. Instead of just firing off an audible alarm, the users wanted the computer to send a voice instruction. Since the number of instructions was fairly small, it wouldn’t have been impractical to record sound files and play the correct one based on an alarm number, but it wouldn’t scale well and keeping clients up-to-date would start to become a challenge.

Instead, a little research turned up the fact that our preferred Linux distribution, Red Hat, includes a speech synthesis system, Festival, with text-to-speech capabilities. Even better, Festival can be run as a daemon that listens on a TCP port. A little bit of shell programming later, and Festival was wrapped as a Linux service. Another bit of Smalltalk code using Totally Objects SocketSet was used to pass text to that service, and we now have generic text-to-speech capability in our application.

Certainly Smalltalk could have been used to implement most of the daemon side of these alarms as well, but some scripting would still have been required. Using the approach we did allows us to keep the installation package light and minimize the skill set required to maintain it in the future. Moreover, testing, troubleshooting and modifications can be done easily from a command prompt the client machine which has a lot of value when you’re trying to fix a problem in a factory a long way from your development environment!

You Can Never Go Home, or Can You?

Over the past several weeks, I’ve been picking up the pieces of a project that I thought I’d finished when I left the TAF back in 2005. However, it seems that my past has returned to haunt me, and I’m once again digging into a server that I’d implemented using VA Smalltalk’s Web Connect and Web Services frameworks.

It’s an eerie feeling returning to a project like this after six years, sort of like returning years later to the house you grew up in. A few changes may have been made here and there, but you can find your way around in the dark. In the case of my project, a couple of people have hacked on it during the intervening years, but the code was largely intact.

One of the biggest initial hurdles I had to overcome was the fact that someone had decided that a slightly different version of the code was needed for use in one of the plants at TAF. The server had been running happily unchanged for over a year. Normally, I would have continued to ignore for a while longer, but it was the last part of my Smalltalk upgrade project, so I had to be able to rebuild the server. This proved to be a challenge.

One of my hard and fast rules is that one should be able to load one single config map into a virgin image to create a specific version of a packaged image.In the case of this server, the specialized code was gathered into its own config map, but the config map itself had no required maps defined. As a guide for building the runtime, the map was completely useless. The map contained applications that were in more general config maps that built other images, but different versions with changes for which there was no documentation. Some of the code changes appeared to be gratuitous, and in other cases, there were methods that referred to methods that couldn’t be found anywhere in the code repository.

I eventually managed to shoe-horn the contents of this map into one of the existing complete maps to complete my migration, but we’ll never know what code was actually running prior to the migration. All we know is that things were working before the migration, and they continued to work after the migration. With the migration complete, I was free to concentrate on the more interesting problem of figuring out why some things that should have been working weren’t anymore, and adding some interesting new functionality.

Browsing Processes

James Robertson’s Smalltalk 4 You 87 looks at process debugging in VA Smalltalk. This reminded me that there’s a great tool wandering the interwebs that makes the task even easier. Back in the dim and hazy past, Jeffrey Odell created the VA Process Browser, a companion to the SUnit Browser that’s found in VA Smalltalk today. It looks like this:

As you can see, it gives you a nice list of all processes currently in the image, along with their current status. The display updates on a periodic basis, or you can manually refresh it. All the things you could reasonably want to do with a process are easily accessible, and the tool itself is launched from the Tools menu of the Transcript window.

Unfortunately, Jeffrey appears to have moved on to other endeavors, and the VA Process Browser code has fallen by the wayside. If you’re out there somewhere, Jeffrey, it would be great if you’d make the source available on VAStGoodies.com, or, if you send the necessary permission, I’d be happy to do it on your behalf. In the meantime, interested parties will need look around or ask the right person to obtain a copy.

Changes to Instantiations’ VA Support Forum

Fans of the Instantiations VA Smalltalk support forum should be aware that the forum is being closed as of May 27. Support is being transitioned to a VA Smalltalk Google Group. This makes it much easier to follow via your favourite RSS reader. The same group, as well as other Smalltalks and Smalltalk-related information, is also available at http://forum.world.st.

A Little Samba

A friend approached me for some Linux help the other day. He wanted to access an SMB/CIFS share on his network attached storage device (NAS) from his Fedora Linux box. I’d actually done something similar in a former life, so it seemed like a relatively simple problem. I assured him that spending some time learning about autofs would quickly get him to where he wanted to be.

In my case, I set up an offsite Linux laptop to make an hourly connection to the company network via VPN, and mount a Windows share. The script would rsync the contents of the Windows share to a local directory, and disconnect. This setup ran happily for a few years with only minor changes for password updates and such.

My friend was less fortunate than I’d hoped. He found a website with some instructions to create a /etc/auto.cifs file that would automagically connect the necessary shares on reference to a dynamically-created directory hierarchy. It sounded great, but, unfortunately, just didn’t work. I poked at it a little while, but, in the end, went with the technique I knew would work. I document it here for posterity. In some cases, where I say I did something, it had actually already been done in the unsuccessful attempt to get things working.

First, I yum install samba-client. The autofs service had already been installed, or else I would have had to do that, too. Then, I make sure that the NAS device was in the Linux machine’s /etc/hosts file (he doesn’t run a Bind server). I create a directory to act as the base for CIFS shares, /cifs (it could be any new directory, arbitrarily deep in the hierarchy.

Let’s assume that the NAS device is named nas, we’re interested in the SMB share myshare on the device, the username we’ll use to access the share is guido, and guido’s password is sarducci. I create a file named /etc/nas.password with two lines:

username=guido
password=sarducci

and after saving it, chmod it to 0600.

I then create, or modify, /etc/auto.master to read

/net -hosts
/cifs /etc/auto.nas --ghost –timeout=60

The --ghost parameter causes any shares mentioned to show in a directory listing even when they’re not actually connected.

The file /etc/auto.nas looks like this:

myshare -fstype=cifs,rw,credentials=/etc/nas.password ://nas/myshare

The above should be on a single line. Additional shares could be added with the same or different credentials. Make sure that this file and all credentials files are chmoded to 0600.

Once the autofs service has been reloaded, you should be able to see files in /cifs/myshare.

The Gist of the Matter

Last time out, I started to talk about introducing a newcomer to Smalltalk. Once the basic question of which environment to use was settled, I took my protégé through one of the hoary, time-honored Smalltalk exercises of writing some broken code in a workspace, and fixing it via the debugger. Inspecting 3 frob: 7 provides some interesting jumping off points, including a chance to talk about the Magnitude hierarchy, Smalltalk’s ability to define methods within the debugger, and where and why one might place a new method, both within a hierarchy, and within categories.

We then got a little more advanced with this:

| dog |
dog := Dog new.
dog bark

We also just typed this into a workspace and used the debugger to define everything needed, from the Dog class to the #bark method. Next, we created a chicken and corresponding class that could cluck. This then provided us with an opportunity to think about a class hierarchy, so we went to the class browser, created an abstract Animal class, and moved our Dog and Chicken classes underneath it.

I then introduced some refactoring. Our Dog>>#bark method,

bark

Transcript cr; show: ‘bow wow’

became

bark

Transcript cr; show: self sound

courtesy of the ‘Extract Method’ refactoring, and then became

bark

self makeSound

by selecting the entire body of the method and extracting that. We then pushed up Dog>>#makeSound to the Animal class.

We attacked Chicken>>#cluck similarly, yielding.

cluck

Transcript cr; show: ‘cluck cluck’

First we extracted our ‘cluck cluck’ string to a #sound method. Then we applied ‘Extract Method’ to the #cluck method body. With that, #cluck became

cluck

self makeSound

after we were offered the chance to reuse the already existing #makeSound method. Even after years of refactoring, the ability of ‘Extract Method’ to find an existing method in the hierarchy matching some arbitrary code impresses me, but when a newcomer sees it for the first time, it’s like magic. If you haven’t explored the power of Smalltalk’s refactorings, you’re programming with one hand tied behind your back.

After a little more work with the code, we decided to wrap up for the day. My protégé wanted to save the day’s progress to share with others. This shouldn’t have been a problem, but it did present a challenge. Pharo’s fileout mechanism produces a file in standard Smalltalk Interchange Format, but whatever line-end convention it uses wasn’t the one used by the platform we were running on, Linux. The resulting file wasn’t particularly readable, so we had to pass it through a filter. The filtered output eventually made its way onto Gist, a code snippet sharing service hosted by Github.

This suggests an opportunity for somebody. Both VA Smalltalk and Pharo offer a Script Manager that ought to integrate very nicely with Gist and/or Github. Anybody care to take it on?

Just Starting Out?

I’ve recently had the opportunity of introducing a newcomer to the world of Smalltalk, something that happens far too infrequently these days.  The neophyte was doing it out of an interest in the language rather than out of an employment requirement, which made it especially important that the experience be as painless and rewarding as possible.

It should be no surprise to any of us that new Smalltalkers are most likely going to be coming to us from the Ruby world.  A large number of them are also Linux or Mac users.  When I have a choice, I use a Mac, but I’m willing to let others make their own mistakes.  As it turns out, the person I was working with was a Linux user, which immediately ruled out a look at Dolphin Smalltalk.  There are, however, a number of Smalltalk environments that do work in Linux.

These days, I spend most of my Smalltalk life in VA Smalltalk from Instantiations, which happens to support Linux, more or less.  Given that I’m supporting an existing environment, I don’t really have a choice, but I’d probably have chosen VA Smalltalk anyway.  There’s absolutely nothing like ENVY for supporting co-located development.  However, for someone approaching Smalltalk for the first time, VA Smalltalk is just too much complexity, even for the installation.  On top of that, the development environment under Linux is just too slow and flakey.   I did a quick demo of the VASt environment on Linux, and my protégé commented on how old the environment looked.  For myself, didn’t want to subject a newcomer to the raft of error messages that kept showing up in the shell window from which VASt was started.

In a past life, I’ve spent a lot of time with Cincom products.  VisualWorks runs quite well on both the Mac and Linux, and they’ve done some excellent work in keeping the environment fresh.  I’d happily have used it for this introduction but Cincom Smalltalk can’t currently be downloaded from their website.  Instead, one has to request that a CD be mailed; this is a significant barrier that will hold back investigation by potential new users.

When Cincom was downloadable, they provided an ISO of the installation disk that included all supported platforms.  I’d strongly recommend to Instantiations that they look at a similar mechanism.  They currently require one to download multiple zip files, unzip each file, step into a subdirectory and then execute a setup program.  After the install is complete, the unzipped directory needs to be removed.  Cincom provided a single download for all environments, and all the installation programs were located in the same directory.

I didn’t even give GNU Smalltalk serious consideration because I find the Smalltalk IDE to be a significant advantage to developers.  It also offers a lot of code one can look at that is already known to be working, since it’s running the IDE. Smalltalk/X offers an IDE, but I’m just not familiar enough with it to risk using it during an introduction. These two Smalltalk dialects certainly have their place, but I don’t think they’re appropriate for newcomers.

Ultimately, we ended up in Pharo, an environment I haven’t really had the opportunity to spend much time with.  After some bad experiences with Squeak a few years ago, I’ve tended to stick with the old standards, but I was pleasantly surprised with the current state of Pharo, and given that much of the current innovation in the Smalltalk world is coming from Pharo, it’s not a bad place to start a newcomer.