From b11d31ef23c5dfee6bfa54afbec47fc8b8bab7b1 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 13 May 2018 15:30:23 +0300 Subject: Change: how controller stores persistent data Replace old State class with new FilePersistentState and TransactionalState classes. Use new Resource class instead of raw dicts. Use context managers for creating, updating resources, to avoid mistakes from accidentally not saving changes. Overall persistence should now be rather simpler. This should open up a possibility for changing the controller to insert more actions into the build graph, to trigger notifcations via the workers. --- ick2/apibase.py | 59 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'ick2/apibase.py') diff --git a/ick2/apibase.py b/ick2/apibase.py index cb0d9f9..aeda00b 100644 --- a/ick2/apibase.py +++ b/ick2/apibase.py @@ -19,10 +19,8 @@ import ick2 class APIbase: def __init__(self, state): - self._state = state - - def get_state(self): - return self._state + assert state is None or isinstance(state, ick2.FilePersistentState) + self._trans = ick2.TransactionalState(state) def get_routes(self, path): return [ @@ -100,12 +98,6 @@ class APIbase: ick2.log.log( 'warning', msg_text='PUT Not found', kwargs=kwargs) return ick2.not_found(e) - except ick2.WrongProjectStatus as e: - ick2.log.log( - 'error', - msg_text='Wrong state for project', - exception=str(e)) - return ick2.bad_request(e) ick2.log.log('trace', msg_text='returned body', body=repr(body)) return ick2.OK(body) return wrapper @@ -149,22 +141,28 @@ class ResourceApiBase(APIbase): self._type_name = type_name def list(self, **kwargs): + resources = self._trans.get_resources(self._type_name) return { - self._type_name: self._state.get_resources(self._type_name), + self._type_name: [r.as_dict() for r in resources] } def show(self, name, **kwargs): - return self._state.get_resource(self._type_name, name) + return self._trans.get_resource(self._type_name, name).as_dict() def create(self, body, **kwargs): - resource = self.mangle_new_resource(body) - name = self.get_resource_name(resource) - try: - self._state.get_resource(self._type_name, name) - except ick2.NotFound: - return self._state.add_resource(self._type_name, name, resource) - else: - raise ick2.ExistsAlready(name) + ick2.log.log( + 'trace', msg_text='create resource', + resource_type=self._type_name, body=body, kwargs=kwargs) + + as_dict = self.mangle_new_resource(body) + rid = self.get_resource_name(as_dict) + if self._trans.has_resource(self._type_name, rid): + raise ick2.ExistsAlready(rid) + + with self._trans.new(self._type_name, rid) as resource: + resource.from_dict(as_dict) + + return as_dict def mangle_new_resource(self, resource): # pragma: no cover return resource @@ -173,17 +171,20 @@ class ResourceApiBase(APIbase): raise NotImplementedError() def update(self, body, name, **kwargs): - name = self.get_resource_name(body) - try: - old = self._state.get_resource(self._type_name, name) - except ick2.NotFound: - raise - else: - resource = self.mangle_updated_resource(old, body) - return self._state.update_resource(self._type_name, name, resource) + rid = self.get_resource_name(body) + if not self._trans.has_resource(self._type_name, rid): + raise ick2.NotFound() + + with self._trans.modify(self._type_name, rid) as resource: + as_dict = self.mangle_updated_resource(resource.as_dict(), body) + resource.from_dict(as_dict) + + return as_dict def mangle_updated_resource(self, old, new): # pragma: no cover return new def delete(self, name, **kwargs): - self._state.remove_resource(self._type_name, name) + if not self._trans.has_resource(self._type_name, name): + raise ick2.NotFound() + self._trans.remove_resource(self._type_name, name) -- cgit v1.2.1