Re: Persistant data with Mason
by bpphillips (Friar) on Feb 11, 2005 at 19:34 UTC
|
if you're needing access to this data from with Mason, you can use Mason's built in data caching. First you create a component file to encapsulate the data you want to share across requests and processes (i.e. "_getSharedData").
# mason component _getSharedData
my $value = $m->cache->get("key");
return $value if(defined($value));
# compute $value here since it hasn't been stored yet
$value = $$;
$m->cache->set(key=>$value);
return $value
Then you can call that component anytime you want to retrieve it.
my $value = $m->comp('/_getSharedData');
Note that Mason's cache, by default, is stored on disk but you can use any Cache::Cache sub-class that you want (Cache::SharedMemoryCache would allow you to share the data across processes without writing it to disk).
$m->cache(cache_class => 'SharedMemoryCache')->set(key=>$value);
$value = $m->cache(cache_class => 'SharedMemoryCache')->get("key");
Also, $m->cache->get("key") is scoped to the component you are calling it from (so don't expect to be able to access the same data from another component without calling _getSharedData
For more info on Mason caching, see the HTML::Mason::Devel docs.
HTH - Brian
| [reply] [d/l] [select] |
|
I believe Cache::Cache recommends using Cache::FileCache rather than Cache::SharedMemoryCache.
Other than that, I agree, a cache is probably the easiest
way to go. Cache::FileCache on a tmpfs or other sort of
ram disk, is quite quick.
Alternatively, as others have suggested, a light weight DB
backend also makes sharing easy.
| [reply] |
|
Thanks, this is actually a very good suggestion. Using the environment won't work, as I'll be accessing the Perl interpreter's %ENV, not Apache's. I might dabble with Shared Memory directly some time, but for now, I think I'll just use Mason's caching capabilities to avoid reinventing the wheel...
| [reply] [d/l] |
Re: Persistant data with Mason
by friedo (Prior) on Feb 11, 2005 at 18:20 UTC
|
In mod_perl, each Apache child process gets its own interpreter. So while package variables will be persistent, each Apache child will have a separate instance. Perhaps a lightweight solution like DB_File or DBD::SQLite might work for your purposes. | [reply] |
Re: Persistant data with Mason
by samizdat (Vicar) on Feb 11, 2005 at 19:02 UTC
|
You want common, persistent memory across all processes? The Environment Variable suggestion is a good one, but if you need fast access to larger memory arrays it has its limits.
I don't know Mason, but IIWM, I'd use Shared Memory (SYSVSHM, in BSD parlance). Look up shmget, shmread, shmwrite. The tricky parts are:
- figuring out how to pass the memory pointer handle to each process
- write-locking the memory
I always write code for webservers I have control of (!), so I can usually simplify the first problem because I can force my allocation to occur before anyone else's, assuring me of a known location. However, if you can get your sysadmin to allow you to allocate a small known mailbox location as the first SHM allocation, then you can use that location as the place to store your application's larger variable array. Failing the availability of this, you can always use a file in a known location. Once this is cached, the performance hit isn't too bad.
SHM is a powerful tool! | [reply] |
Re: Persistant data with Mason
by Fletch (Bishop) on Feb 11, 2005 at 18:22 UTC
|
| [reply] |
Re: Persistant data with Mason
by injunjoel (Priest) on Feb 11, 2005 at 20:40 UTC
|
| [reply] |
Re: Persistant data with Mason
by trammell (Priest) on Feb 11, 2005 at 19:41 UTC
|
If you're using your own handler.pl, you could just define whatever constants you need as globals there.
If you don't like any of these suggestions, you should contact [id://autarch]. He's one of Mason's authors. | [reply] |
|
I may be wrong, but I think this is not true. Anything you define as global in your handler.pl is global for the apache child and not for all apache childs together. They remain independent. You still need to pas by the cache method suggested by 'bpphillips' to exchange information between the processes.
I thinks that's why 'crenz' also says: "anything placed in a %once block in Mason seems to be executed for each request"
In his test environment, each request done sometimes done by the same child, sometimes by another. That's way he sees sometimes the correct behaviour, but mostly the faulty one due the low charge of his server (each time a fresh apache child!).
Mason guarantees that everything placed in a %once block is only executed once for the apache child. In this way you can setup all necessary connections and initializations (DB, Init files, ...) for each of the apache childs.
| [reply] |
|
| [reply] |
|
Re: Persistant data with Mason
by holli (Abbot) on Feb 11, 2005 at 18:26 UTC
|
You could use the environment for that.
.oO(if you are allowed to set variables in the environment)
| [reply] |