. .

smalltalk

More Predictable than RTP

January 14, 2011 9:47:24.364

I've been building BottomFeeder without RTP for awhile now, but until I started looking at build automation for this new job, I hadn't fully automated it. That's something I've done now, and one thing that I really like about the process I use is the predictability.

With RTP, if you let it scan and strip, you're never really sure what it took out. Oh, sure, there's a report it generates, and you can go through that - but it's not easy to digest. Instead, I have a script that pulls out a set of named packages - this is one of the advantages to the newer releases of VW, btw - having defined blobs of code that have structure not only makes loading easier, it makes unloading easier. Here's what I have my script do:

"Unload the debugger and other tools"
(Store.Registry pundleNamed: 'Tools-Debugger')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].
(Store.Registry pundleNamed: 'Tools-Refactoring Browser')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].
(Store.Registry pundleNamed: 'Tools-Parcel Manager')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].
(Store.Registry pundleNamed: 'Tools-Changes')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].
(Store.Registry pundleNamed: 'Tools-File Browser')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].
(Store.Registry pundleNamed: 'UIPainter')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].
(Store.Registry pundleNamed: 'StoreForPostgreSQL')  ifNotNil: [:pundle |
	pundle leafItems do: [:each | each markNotModified].
	[pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex
	resume: true]].

The handler block allows the script to proceed if anything odd happens; I should probably be logging those events. The larger point is this: I know exactly what got pulled, and, more importantly - what didn't. Unless you're really careful (and you have to be careful every time code has changed), RTP will strip code from your application. That's usually safe, but if you use constructed message sends for any reason (good or bad), you can get smacked. I think this approach is vastly safer.

I've posted before on how I put the image into a runtime state, but it's worth going over again:

  • Have a subclass of UserApplication. Specify your prereq subsystems, and implement #main. In that method, start your application. It'll get called when it's safe to do so at startup, based on the prereqs you specified
  • Execute the following code after you do whatever other image prep is necessary:

"set up logging and exception handling"
DeploymentOptionsSystem current startInRuntime: true.
Notifier current: RuntimePackager.RuntimeEmergencyNotifier.
RuntimePackager.RuntimeManager errorLogPath: 'error.log'.
Notifier logToFile: true.
"set up runtime state"
UI.WindowManager noWindowBlock: [:windowManager | ].
stream := WriteStream on: String new.
stream nextPutAll: 'changeRequest'; cr; cr; tab.
stream nextPutAll: '^true'.
VisualLauncher compile: stream contents.
VisualLauncher allInstances do: [:each | each closeAndUnschedule.  each release].
ObjectMemory garbageCollect.
Workbook allInstances do: [:each | each closeRequest].
(Delay forSeconds: 20) wait.
Parcel searchPathModel value: (List with: (PortableFilename named: '.')).
SourceFileManager default discardSources.

"Now save the image such that this file doesn't get looked for at startup"
[ObjectMemory permSaveAs: runtime' thenQuit: false] fork.
[(Delay forSeconds: 25) wait.
RuntimeSystem isRuntime ifFalse: [ObjectMemory quit]] fork.

I actually use some of the RTP infrastructure (the runtime exception handler and logging) - I just don't use it to create the image. It's a pretty simple process, and once you have the script created, it's easy to have a "one button click" UI drive it - from another image

posted by James Robertson

 Share Tweet This

smalltalk

Getting the Comments for a Store Publish

January 13, 2011 14:33:17.471

You would think that getting the version comment for a package or bundle you've published to Store would be simple - there's a method called #versionComment right there in Pundle - but you would be mistaken. No, that's not the comment you type into the text field when you publish.

Why do I care? Well, as part of my build automation work, I'm generating a small report, and part of that report involves pulling out the comment for a published package. That takes more work to get at than you might think:

 

pkg := (Store.Package withName: 'PkgNameHere' version: 'versionStringHere') first.
blessing := (Blessing 
				blessingsForRecordID: pkg  primaryKey
				type: pkg  typeStringForBlessing) first.
comment := blessing getCommentString.

 

Just tracing Store code to figure that out was painful; the comparison tool Version Browser doesn't make it obvious. Then there's the whole head scratching nature of "why isn't there a method that does this for me in Pundle?" Anyway, that does the job I wanted, and now I have that bit of my reporting task handled.

posted by James Robertson

 Share Tweet This

smalltalk

Registration for Smalltalk Solutions

January 12, 2011 23:33:20.673

Smalltalk Solutions

With the STIC site down, the registration information page is inaccessible. Fortunately, you can still register (and get early bird rates):

In the meantime, perhaps STIC should have someone edit the Apache configuration on their server, remove the redirect to the (non functional) WordPress site, and put up a static page with some basic links on it - at least until they get the problem solved.

Update: Sometime while I was asleep, the site came back :)

Technorati Tags: ,

posted by James Robertson

 Share Tweet This

smalltalk

Smalltalk Solutions Stuff

January 12, 2011 13:37:33.465

Smalltalk Solutions

I'll be at StS 2011, giving a talk on Smalltalk on the server side, focusing on cloud services. I still need to register - as I write this, the STIC website (where the registration page lives) is down though. I'll get to it when the site pops back online :)

posted by James Robertson

 Share Tweet This

smalltalk

Automated Testing for Seaside Apps

January 12, 2011 9:14:05.000

Tony Fleig talks about using a set of open source web tools to automate the testing of a Seaside app:

The WebClient package includes a simple and easy to use HTTP client. Soup is a port of the Beautiful Soup Python HTML/XML parser designed for screen-scraping. The combination of these two made it possible to perform black-box testing of my Seaside web application.

Technorati Tags: ,

posted by James Robertson

 Share Tweet This

smalltalk

XTreams For Squeak and Pharo

January 12, 2011 7:08:40.089

Martin Kobetic has ported the latest XTreams code over to Squeak and Pharo:

Hope it's OK to cross-post this, I figured there might be interested people on both sides. I finished the updates of the Xtreams port to match the VW version, so everything (that is available) should work as advertised in the documentation .

Technorati Tags: , ,

posted by James Robertson

 Share Tweet This

smalltalk

Looking at VA Smalltalk

January 11, 2011 8:24:53.807

The next podcast on the schedule will involve a look at where Instantiations is taking VA Smalltalk. Dave Buck and I will be talking to Mike Taylor, President and CEO of the company. If you have anything you would like us to ask Mike, email me before 5 PM EST today. The podcast will be out on Sunday, as per our regular schedule.

posted by James Robertson

 Share Tweet This

smalltalk

Build Oddities

January 10, 2011 14:56:39.232

I'm still working on build tools for the project I'm on, and I ran into an interesting thing today - a package that, when I have a script unload it, the script stops working.

Short explanation: I start by building an image from scratch using Store. From there, I unload a bunch of development tools. That works fine, unless I do the following:


(Store.Registry pundleNamed: 'StoreBase') ifNotNil: [:pundle |
      pundle leafItems do: [:each | each markNotModified].
      [pundle markNotModified; unloadFromImage] on: Warning do: [:ex | ex resume: true]].

Once I unload StoreBase, the build script I'm using (via -fileIn at the command line) simply stops working. No error messages either; the image just sits there, blinking at me. Very odd, but for now I'm dealing with that by just leaving StoreBase alone. I think I'll have to try it with that handler block left off, just so I can track the problem down.

posted by James Robertson

 Share Tweet This

smalltalk

Virtual Agility

January 6, 2011 21:26:25.598

Ron Teitelbaum talks about how Teleplace supports agile development - no matter how far flung your development team is.

Technorati Tags: ,

posted by James Robertson

 Share Tweet This

smalltalk

Building Clean

January 6, 2011 14:08:00.604

Before you can even get to building a runtime image from a clean base image, you have to get to the point where yoiu can build a clean development image from a clean base image. That was today's first challenge.

On any long lived project, things pile up if no one has been doing clean builds, and this one was no different. It wasn't bad - I only ran into one issue that needed resolving: four methods in one package were being invoked (via package initialization code), but those methods were defined in a package that hadn't loaded yet.

To back up a bit, the entire project here is in a "master bundle" - you load that, and you get everything (either in the bundle or via pre-reqs). Over the last little while, builds have only been done on top of previous development images, so no one spotted this issue. I cleaned that up, and then everything came in easily.

Next up was trying to save the bundle out as a parcel (I'd like to be able to build into an image without Store present). Now I ran into the second check: a bunch of external interfaces were defined with optimization level #debug, and parcels can't be saved with that setting. So... another bunch of small changes and bam - I had a parcel out on disk.

Now comes the fun part - one of the pre-reqs is all of the patch sets that Cincom support sends out (boy, would this be simpler if they just shipped new versions of the owning packages, but I digress). That stuff can't be saved (at least in VW 7.6) as a parcel, because they all contain overrides. So... I just filed that out. Since it's all patches on the base system, I can just set that up to load last and I shouldn't run into problems.

Thus far, I have the system loading cleanly from a base visual.im, which is progress. From there, I can move along to the next few steps and see if I can get a runtime build. Fingers crossed :)

posted by James Robertson

 Share Tweet This

Previous Next (1107 total)