[Seaside] Application context

James Foster Smalltalk at JGFoster.net
Sun May 17 23:11:11 UTC 2009


On May 17, 2009, at 3:23 PM, Pat Maddox wrote:

> Hey James,
>
> Thanks for the reply.  Comments inline
>
> On Sun, May 17, 2009 at 2:32 PM, James Foster  
> <Smalltalk at jgfoster.net> wrote:
>> Hi Pat,
>>
>> As I understand it you want application data to be separated based  
>> on entry
>> points, but otherwise share the same environment (e.g., deployment  
>> image).
>
> Well my real goal is to have a single place where I wire up my app's
> major dependencies - repositories, connections to external services,
> etc.  This is partly so I can do multiple installs, but mostly for
> ease of use.

Do different entry points share data? Does one application have  
multiple entry points? Does one deployment have multiple applications?  
What do you mean by "multiple installs"?

>> If you will have a small number of pre-defined entry points, then  
>> you could
>> have separate components for each entry point and subclass from a  
>> common
>> ancestor so that they share behavior. With this approach you could  
>> define a
>> 'class instance variable' in the abstract superclass and then each  
>> subclass
>> would have its own data.
>
> This makes sense to me but I'm not sure how to make it work.  If I
> have a class instance variable, then each subclass gets its own
> version of that variable.  The whole point of this is to share one
> object throughout all components in an application.

True enough. This would not share data among multiple components.

>> Alternatively, you could use the entry point as a key in a Dictionary
>> containing various different application data sets. You can get the  
>> entry
>> point from 'self session baseUrl printString' or 'self session  
>> baseUrl path
>> last'. With this approach you can keep your class variable, but  
>> make it a
>> Dictionary and do similar lazy initialization of the Dictionary and  
>> of the
>> contents (using #'at:ifAbsentPut:').
>
> I still need to know where to put this Dictionary though.  I take it
> that a class variable in my WAComponent subclass is not such a bad
> idea after all?

If you are storing objects in the image (or GemStone repository), then  
the objects need to be reached from a persistent root. In Squeak, that  
root is the global named Smalltalk. In GemStone there is a global  
named UserGlobals that should be available. You can attach your  
dictionary to that global or you can attach it to something that is  
referenced from that global. Since classes are themselves globals,  
anything they reference, including class (instance) variables, are  
also persistent.

The class (instance) variable approach is quite reasonable, though you  
might think about what class to use. Instead of having every domain  
object keep a cache of its instances, you might have a single  
'Database' class that has instance variables for various things. In  
our Los Boquitas example, instead of having LBEvent hold on to a  
collection of events, you could define a LBTeam class with instance  
variables for players, coaches, events, etc. You could even generalize  
it further to have a LBLeague class with a collection of teams. (Or  
more general, a LBCommunity class with a collection of leagues...)

Basically, we are using the Singleton Pattern (http://en.wikipedia.org/wiki/Singleton_pattern 
). Create a singleton for whatever is truly singular in your object  
space, and then hold on to it in a class (instance) variable. Have  
that singleton manage whatever data you want to persist.

>> Also, depending on your deployment strategy, you could use multiple
>> Smalltalk images. This "horizontal scaling" is a simplification of  
>> the
>> approach taken by DabbleDB and allows hundreds of thousands of  
>> applications
>> with the same code but different data and uses multiple machines
>> efficiently.
>
> Yes I certainly need to figure out how I want to deploy this stuff.
> That kind of strategy would work really well for this particular app.
> But I'm also interested in "out of the box" (and cool! (and pricey ;))
> behavior with gemstone.

The basic idea is model your domain objects. Somewhere, there should  
be a singleton that knows about the various applications, customers,  
etc. You could even name your singleton 'Pat'!

> Pat
>
>
>>
>> James Foster
>>
>> On May 17, 2009, at 1:49 PM, Pat Maddox wrote:
>>
>>> Where's a good place for me to do one-time setup and then make  
>>> certain
>>> objects available to the rest of the application?  I created a
>>> UserRepository that I want each of the components to use.  So far  
>>> I've
>>> created a base subclass of WAComponent, it has a class variable  
>>> named
>>> TheUserRepository.  I have a class-side method which lazily
>>> instantiates it.  Then the instance initialize for each of my
>>> components points an instance variable at this method.  The code  
>>> looks
>>> like
>>>
>>> "ANComponent userRepository"
>>> userRepository
>>>        TheUserRepository ifNil: [TheUserRepository := GDRepository  
>>> for:
>>> ANUser].
>>>        ^ TheUserRepository
>>>
>>> "ANComponent>>initialize"
>>> initialize
>>>        super initialize.
>>>        userRepository := ANComponent userRepository.
>>>
>>> All of my components inherit from ANComponent so they each have the
>>> userRepository set when they're instantiated.
>>>
>>> Is this a good way of doing it?  It seems to be working so far.  I
>>> don't know enough about seaside to know better at this point :)
>>>
>>> If possible, I'd like to move away from using a class variable to
>>> store the repo.  As it is, I can't deploy the same app twice at
>>> different entry points because they'll use the same userRepository
>>> object.  So what I'd really like is an Application object that gets
>>> run once, where I can do all my setup.  But that application object
>>> should be new for each deployment, so that I'm not mixing the data
>>> between deployments.
>>>
>>> Thanks for any help.
>>>
>>> Pat


More information about the seaside mailing list