> I know the use of an HTTP request was previously marked as
> a poor idea, however I'm not sure I agree as I've thought
> this through. Here's a solution that I think would work
> quite well, assuming you encapsulate all your app vars in
> a single object (which is a good idea anyway, IMO).  Of
> course, I might be suggesting rebuilding JMS, which I know
> exactly nothing about, but oh well.

Yea, my one large project (Tapestry) does encapsulate all its application
variables into its own structure, however, in this case it doesn't help much
using what you've described below, and I'll explain why here in a moment.

>  - server 1 learns it needs to update it's app vars
>  (exactly how is app dependant).
>  - server 1 updates the app vars object however it needs to.

This much is already being done prior to clustering, so we're okay here.

>  - server 1 serializes the app vars object
>    (probably want XML, rather than the built in binary format).

That's an idea... Although if the application is rather large (and caches a
lot of data), serializing the structure into an xml packet whether it's wddx
or otherwise could be rather time consuming. At some point, xml
serialization then defeats the purpose of cacheing data in the application
scope instead of going to the db server every time, so imho it's much better
to just deal with the data that's been changed. It could be that you pass
both an xml packet and a string representing the path to the data you're
updating, such as

<xml blah blah> ... </xml>
application.myapp.someobject.stuff.3XLN7

and the clustered app receiving this messag then coppies the deserialized
content of that xml packet into the indicated variable. Should take a lot
less time than serializing the entire application.myapp structure.

>  - server 1 gets a list of cluster members (exactly how
>    will be app/container/cluster controller dependant).

I'd go for a cachedafter query here. This allows me to not have to
continually go to the db to get the list of server and use the same
application sharing routine to flush the cachedafter timestamp and update
the query to then add a new server to the list without having to do anything
special like restarting the application or worse restarting the cf server.

>  - for each server, server 1 calls a secured web service,
>    passing the serialized app vars object, which the other servers then
>    deserialize and store in their app scope.

I don't know that it needs to be a web service. I could do the same thing
with CF5 and "secure" it by using a password or password-like algorithm, or
better yet by only allowing other servers in the cluster to submit to the
page receiving the data using the same server list that was used on the
sending end and matching that list against the cgi.remote_addr variable. And
what might actually be a best case scenario is to have each individual
server in the cluster have a single receive-from and send-to address, such
that the cluster is linked in a ring like a token-ring network or a
web-ring. ;P The signal sent from the originating server is sent to only one
machine which then receives it and serializes it in a queue using <cflock
name="[myappname]_appshare"> with a long timeout limit in addition to any
locking on the application scope -- this would just ensure that all the
appshare commands are processed in sequential order. If a given machine in
the ring is down or otherwise inaccessible, the machine attempting to send
to it moves on to the next machine in the list when it doesn't get an "ok"
response, so that any individual server in the ring won't break the entire
mechanism. The ring itself ensures that the load created by the routine is
distributed evenly amongst the servers and that refresh commands are
processed in sequence. And this of course solves the problem described
below.

> The last piece of the puzzle would be making sure more
> than one server
> doesn't start that process at any given time, but that
> shouldn't be a big
> deal.  Call another web service method after step one that
> tells all servers
> not to start updating, and handle collisions  (if two
> servers start down
> that new step at the same time) by alphabetic ordering of
> server name or
> something.

> Feel free to tell me I'm a jackass, but that seems to me
> like it'd work
> well, and be very app independant, so it could be reused
> over and over.

Not a jackass, it was much the same sort of mechanism I had in mind but
wasn't entirely keen on using. Although now that I've read yours and put
some more thought into it I'm a little less anxious about actually
implementing it.

I'm still concerned about sending an xml packet between the machines and I
think I have a solution for that as well. All servers in the cluster
retrieve their cache data initially from the same source (a single db or a
clustered db, but it's all the same data in either case). That data from the
db is then cached in the application scope. And in the case of my
application in many instances it's already choosing to simply delete data
from the application scope rather than writing over it, which then forces
the application to go back to the db when the data doesn't exist in the
application scope. So the simplest solution (without going to JMS) is to
send a one-line command to each machine in the ring with two variables
indicating the originating server and the application data to refresh. The
receiving server deletes the variable, sends the "ok" response back and then
sends the same command on to the next server in the list and waits for the
ok back. If it doesn't receive the ok, it moves on to the next server in the
ring until it receives an ok or reaches the originating server.

And best of all, to prevent this process from slowing the users down, you
run the routine from the originating server using request scope data in the
OnRequestEnd.cfm template after a <cfflush> tag. Only the first request
occurs on a user requested page (and that only after the page has been
delivered) -- remaining requests occur in the "ether" between the machines
and so no one is affected (speed of delivery) by those transactions. And
since the data's being deleted and then automatically recreated from source
on demand, you don't have to worry about anyone having cache data that's
"out of sequence".

s. isaac dealey                954-776-0046

new epoch                      http://www.turnkey.to

lead architect, tapestry cms   http://products.turnkey.to

tapestry api is opensource     http://www.turnkey.to/tapi

certified advanced coldfusion 5 developer
http://www.macromedia.com/v1/handlers/index.cfm?ID=21816

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
Archives: http://www.houseoffusion.com/cf_lists/index.cfm?forumid=4
Subscription: 
http://www.houseoffusion.com/cf_lists/index.cfm?method=subscribe&forumid=4
FAQ: http://www.thenetprofits.co.uk/coldfusion/faq
This list and all House of Fusion resources hosted by CFHosting.com. The place for 
dependable ColdFusion Hosting.

                                Unsubscribe: 
http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
                                

Reply via email to