On Sunday 29 July 2007, Brian Reichert wrote: > The background: I often use SDBM-tied hashes to share cheap slow > data across concurrent apps. Not much luck under Mason. > > I've cobbled together a Mason handler.pl that maintains such a tied > hash as a global variable. > > I've written a component that lets me get/set a value in this tied > hash. > > The symptom I see that after a 'set', subsequent 'gets' show me > various results; sometimes the data comes back set, sometimes not.
Your data isn't being shared between the processes, so you're only getting the data back if your request happens to hit the same apache process. If I recall correctly, tied hashes aren't written to their data source until they are deleted. If you are using a global under mod_perl, then that isn't until the child terminates - remember mod_perl is a persistent perl environment, your script does not exit and clean up at the end of the request - any globals persist across requests. > Here, HASH(foo) is my tied hash reference, followed by the PID of > the apache process handling the request, and a bit representing > whether or not my data is seen as set in the tied hash. Two complete > loops over all of my http pids: > mod_info is HASH(0x9e0f0e4) 8846 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8839 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8840 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8841 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8844 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8845 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8838 1 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8847 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8846 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8839 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8840 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8841 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8844 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8845 0 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8838 1 at /var/www/html/error_test line 35. > mod_info is HASH(0x9e0f0e4) 8847 0 at /var/www/html/error_test line 35. > > You can see that the hash ID never alters; seemingly, it's always > the same hash. The logs make it seem that only one of my httpd > PIDs made the change. It's not the same hash, it's a hash at the same memory location in each of your processes. If your process is deterministic and the hash is created either in the apache parent or at the same point after forking, then it will get the same memory address in each child. If you look at the above, process 8838 has the altered data, and none of the other processes do. > If I perform these same experiments with command-line tools, the > multiple processes show the data being written to the disk within > a second or so, and all of the processes showing that tied hash > reflect the change quickly. > At the end of this message is a simple tool to demonstrate what I > expect, save as 'dbreader'. Just takes key/value pairs on the > command line, writes to the tied hash, then loops, displaying the > contents of the hash. Does it work under plain mod_perl, without Mason? Remember Mason does it's own perl code generation, and if you aren't careful ir's easy to make unintentional closures -- "Ever had a long talk with ambassador Delenn, Commander?" "Yes, from time to time. Why?" "She and the universe .. seem to have a special relationship." "Don't we all?" - Sheridan and Ivanova in Babylon 5:"A Distant Star"