PageMaker » History » Version 1
Elmer de Looff, 2012-04-23 19:08
PageMaker talk about the persistent storage.
1 | 1 | Elmer de Looff | h1. PageMaker |
---|---|---|---|
2 | 1 | Elmer de Looff | |
3 | 1 | Elmer de Looff | |
4 | 1 | Elmer de Looff | h2. Persistent storage between requests |
5 | 1 | Elmer de Looff | |
6 | 1 | Elmer de Looff | µWeb allows you to store objects in a process-persistent storage. This means that the storage will be properly persistent and available when µWeb is in [[standalone]] mode. When running on top of [[apache]], this persistence is only as good as the apache process, which is typically a couple hundred to a few thousand requests. |
7 | 1 | Elmer de Looff | |
8 | 1 | Elmer de Looff | h3. Default users of the persistent storage |
9 | 1 | Elmer de Looff | |
10 | 1 | Elmer de Looff | By default, the [[TemplateParser]] and the various database connectors are stored in the persistent storage. This has the benefit that pre-parsed templates will not need to be read from disk on subsequent requests. For databases the benefit is that connections need not be made on-the-fly, but can mostly be retrieved from the storage. |
11 | 1 | Elmer de Looff | |
12 | 1 | Elmer de Looff | h3. Storing persistent values |
13 | 1 | Elmer de Looff | |
14 | 1 | Elmer de Looff | Storing persistent values is done with the @Set@ method, as follows: |
15 | 1 | Elmer de Looff | |
16 | 1 | Elmer de Looff | <pre><code class="python"> |
17 | 1 | Elmer de Looff | def _PostInit(self): |
18 | 1 | Elmer de Looff | if 'connection' not in self.persistent: |
19 | 1 | Elmer de Looff | self.persistent.Set('connection', self._MakeConnection()) |
20 | 1 | Elmer de Looff | </code></pre> |
21 | 1 | Elmer de Looff | |
22 | 1 | Elmer de Looff | In the example above, the database connection is only created, and added to the persistent storage, if it's not already present. This way expensive but reusable actions can be optimized by performing them only once (or once every few so many requests, if running on Apache). |
23 | 1 | Elmer de Looff | |
24 | 1 | Elmer de Looff | h3. Retrieving persistent values |
25 | 1 | Elmer de Looff | |
26 | 1 | Elmer de Looff | Retrieving stored values works much like this, but uses the @Get@ method: |
27 | 1 | Elmer de Looff | |
28 | 1 | Elmer de Looff | <pre><code class="python"> |
29 | 1 | Elmer de Looff | def DatabaseAccess(self): |
30 | 1 | Elmer de Looff | with self.persistent.Get('connection') as cursor: |
31 | 1 | Elmer de Looff | cursor.Execute('INSERT INTO `message` SET `text` = "success!"') |
32 | 1 | Elmer de Looff | </code></pre> |
33 | 1 | Elmer de Looff | |
34 | 1 | Elmer de Looff | This uses the connection we created (or still had) during @_PostInit@, and uses it to update the database. |
35 | 1 | Elmer de Looff | |
36 | 1 | Elmer de Looff | In case a key has is not present in the persistent storage (because it wasn't set in the process' lifetime or because it was exlicitly dropped), the @Get@ method has an optional second argument, that is returned when the key is not present: |
37 | 1 | Elmer de Looff | |
38 | 1 | Elmer de Looff | <pre><code class="python"> |
39 | 1 | Elmer de Looff | def FirstVisit(self): |
40 | 1 | Elmer de Looff | when = self.persistent.Get('first_visit_time', 'just now') |
41 | 1 | Elmer de Looff | return 'Your first visit was %s.' % when |
42 | 1 | Elmer de Looff | </code></pre> |
43 | 1 | Elmer de Looff | |
44 | 1 | Elmer de Looff | This will return the stored date and time when there was a previously recorded visit, or the text _just now_ if there was no previous time logged. |
45 | 1 | Elmer de Looff | |
46 | 1 | Elmer de Looff | Finally, the persistent storage has a @SetDefault@ method, that acts much like the similarly named dictionary method. It returns the value for the given key, but if it's not present, it will set the key to the provided value, and return it as well. With this, we can improve on our first-visit tracker, and in one call retrieve or store the first time someone visited: |
47 | 1 | Elmer de Looff | |
48 | 1 | Elmer de Looff | <pre><code class="python"> |
49 | 1 | Elmer de Looff | def FirstVisit(self): |
50 | 1 | Elmer de Looff | when = self.persistent.SetDefault('first_visit_time', datetime.datetime.now()) |
51 | 1 | Elmer de Looff | return 'Your first visit was %s.' % when |
52 | 1 | Elmer de Looff | </code></pre> |
53 | 1 | Elmer de Looff | |
54 | 1 | Elmer de Looff | h3. Deleting persistent values |
55 | 1 | Elmer de Looff | |
56 | 1 | Elmer de Looff | If for any reason you need to delete a value from the persistent storage, this can be done using the @Del@ method. The given key name is removed from the storage. *N.B.:* If the key was already removed from the storage (this can happen if the delete code runs more than once, or the key was not defined in the process' lifetime), no error is raised. It is assumed that removing the key is the only desired action. |
57 | 1 | Elmer de Looff | |
58 | 1 | Elmer de Looff | |
59 | 1 | Elmer de Looff | <pre><code class="python"> |
60 | 1 | Elmer de Looff | def DeletePersistentKey(self, key): |
61 | 1 | Elmer de Looff | self.persistent.Del(key) |
62 | 1 | Elmer de Looff | </code></pre> |