57 self.cnxtype = cnxprops.cnxtype |
57 self.cnxtype = cnxprops.cnxtype |
58 self.creation = time() |
58 self.creation = time() |
59 self.timestamp = self.creation |
59 self.timestamp = self.creation |
60 self.is_internal_session = False |
60 self.is_internal_session = False |
61 self.is_super_session = False |
61 self.is_super_session = False |
|
62 self.default_mode = 'read' |
62 # short cut to querier .execute method |
63 # short cut to querier .execute method |
63 self._execute = repo.querier.execute |
64 self._execute = repo.querier.execute |
64 # shared data, used to communicate extra information between the client |
65 # shared data, used to communicate extra information between the client |
65 # and the rql server |
66 # and the rql server |
66 self.data = {} |
67 self.data = {} |
108 assert prop == 'lang' # this is the only one changeable property for now |
109 assert prop == 'lang' # this is the only one changeable property for now |
109 self.set_language(value) |
110 self.set_language(value) |
110 |
111 |
111 # connection management ################################################### |
112 # connection management ################################################### |
112 |
113 |
|
114 def keep_pool_mode(self, mode): |
|
115 """set pool_mode, e.g. how the session will keep its pool: |
|
116 |
|
117 * if mode == 'write', the pool is freed after each ready query, but kept |
|
118 until the transaction's end (eg commit or rollback) when a write query |
|
119 is detected (eg INSERT/SET/DELETE queries) |
|
120 |
|
121 * if mode == 'transaction', the pool is only freed after the |
|
122 transaction's end |
|
123 |
|
124 notice that a repository has a limited set of pools, and a session has to |
|
125 wait for a free pool to run any rql query (unless it already has a pool |
|
126 set). |
|
127 """ |
|
128 assert mode in ('transaction', 'write') |
|
129 if mode == 'transaction': |
|
130 self.default_mode = 'transaction' |
|
131 else: # mode == 'write' |
|
132 self.default_mode = 'read' |
|
133 |
113 def get_mode(self): |
134 def get_mode(self): |
114 return getattr(self._threaddata, 'mode', 'read') |
135 return getattr(self._threaddata, 'mode', self.default_mode) |
115 def set_mode(self, value): |
136 def set_mode(self, value): |
116 self._threaddata.mode = value |
137 self._threaddata.mode = value |
117 mode = property(get_mode, set_mode, |
138 mode = property(get_mode, set_mode, |
118 doc='transaction mode (read/write), resetted to read on ' |
139 doc='transaction mode (read/write/transaction), resetted to' |
119 'commit / rollback') |
140 ' default_mode on commit / rollback') |
120 |
141 |
121 def get_commit_state(self): |
142 def get_commit_state(self): |
122 return getattr(self._threaddata, 'commit_state', None) |
143 return getattr(self._threaddata, 'commit_state', None) |
123 def set_commit_state(self, value): |
144 def set_commit_state(self, value): |
124 self._threaddata.commit_state = value |
145 self._threaddata.commit_state = value |
143 self.repo._free_pool(pool) |
164 self.repo._free_pool(pool) |
144 raise |
165 raise |
145 self._threads_in_transaction.add(threading.currentThread()) |
166 self._threads_in_transaction.add(threading.currentThread()) |
146 return self._threaddata.pool |
167 return self._threaddata.pool |
147 |
168 |
148 def reset_pool(self): |
169 def reset_pool(self, ignoremode=False): |
149 """the session is no longer using its pool, at least for some time""" |
170 """the session is no longer using its pool, at least for some time""" |
150 # pool may be none if no operation has been done since last commit |
171 # pool may be none if no operation has been done since last commit |
151 # or rollback |
172 # or rollback |
152 if self.pool is not None and self.mode == 'read': |
173 if self.pool is not None and (ignoremode or self.mode == 'read'): |
153 # even in read mode, we must release the current transaction |
174 # even in read mode, we must release the current transaction |
154 pool = self.pool |
175 pool = self.pool |
155 try: |
176 try: |
156 self._threads_in_transaction.remove(threading.currentThread()) |
177 self._threads_in_transaction.remove(threading.currentThread()) |
157 except KeyError: |
178 except KeyError: |
163 |
184 |
164 def _touch(self): |
185 def _touch(self): |
165 """update latest session usage timestamp and reset mode to read""" |
186 """update latest session usage timestamp and reset mode to read""" |
166 self.timestamp = time() |
187 self.timestamp = time() |
167 self.local_perm_cache.clear() |
188 self.local_perm_cache.clear() |
168 self._threaddata.mode = 'read' |
189 self._threaddata.mode = self.default_mode |
169 |
190 |
170 # shared data handling ################################################### |
191 # shared data handling ################################################### |
171 |
192 |
172 def get_shared_data(self, key, default=None, pop=False): |
193 def get_shared_data(self, key, default=None, pop=False): |
173 """return value associated to `key` in session data""" |
194 """return value associated to `key` in session data""" |
299 self._touch() |
320 self._touch() |
300 self.commit_state = None |
321 self.commit_state = None |
301 self.pending_operations[:] = [] |
322 self.pending_operations[:] = [] |
302 self.transaction_data.clear() |
323 self.transaction_data.clear() |
303 if reset_pool: |
324 if reset_pool: |
304 self.reset_pool() |
325 self.reset_pool(ignoremode=True) |
305 |
326 |
306 def rollback(self, reset_pool=True): |
327 def rollback(self, reset_pool=True): |
307 """rollback the current session's transaction""" |
328 """rollback the current session's transaction""" |
308 if self.pool is None: |
329 if self.pool is None: |
309 assert not self.pending_operations |
330 assert not self.pending_operations |
324 finally: |
345 finally: |
325 self._touch() |
346 self._touch() |
326 self.pending_operations[:] = [] |
347 self.pending_operations[:] = [] |
327 self.transaction_data.clear() |
348 self.transaction_data.clear() |
328 if reset_pool: |
349 if reset_pool: |
329 self.reset_pool() |
350 self.reset_pool(ignoremode=True) |
330 |
351 |
331 def close(self): |
352 def close(self): |
332 """do not close pool on session close, since they are shared now""" |
353 """do not close pool on session close, since they are shared now""" |
333 self._closed = True |
354 self._closed = True |
334 # copy since _threads_in_transaction maybe modified while waiting |
355 # copy since _threads_in_transaction maybe modified while waiting |