Example #1
0
    def check_downgrade(self, obj_id: str, owner: str) -> None:
        """Check if lock can be downgraded to single object lock."""

        raise_msg = f"{obj_id} lock is not owned by {owner}."
        if obj_id not in self.write:
            raise LockingException(raise_msg)

        if owner != self.write[obj_id]:
            raise LockingException(raise_msg)

        if not self.tree:
            raise LockingException(
                f"Nothing to downgrade for {obj_id} and owner {owner}.")
Example #2
0
    def check_upgrade(self, obj_id: str, owner: str) -> None:
        """Check if lock can be upgraded to whole locked tree."""

        raise_msg = f"{obj_id} lock is not owned by {owner}."
        if obj_id not in self.write:
            raise LockingException(raise_msg)

        if len(self.write) > 1:
            raise LockingException(raise_msg)

        if owner != self.write[obj_id]:
            raise LockingException(raise_msg)

        if self.tree:
            raise LockingException(
                f"Nothing to upgrade for {obj_id} and owner {owner}.")
Example #3
0
async def ensure_read_locked(obj_id: str,
                             owner: str,
                             locked_tree: bool = False) -> None:
    """Check if object is read locked."""

    if not await glob.LOCK.is_read_locked(obj_id, owner):
        raise LockingException("Object is not write locked.")
Example #4
0
async def start_scene_cb(req: srpc.s.StartScene.Request, ui: WsClient) -> None:

    scene = glob.LOCK.scene_or_exception()

    if get_scene_state(
    ).data.state != sevts.s.SceneState.Data.StateEnum.Stopped:
        raise Arcor2Exception("Scene not stopped.")

    # online scene can't be modified so we demand that UIs free all their locks first
    # when editing project, changes can be done both online and offline
    if not glob.LOCK.project and await glob.LOCK.get_write_locks_count():
        raise LockingException(glob.LOCK.ErrMessages.SOMETHING_LOCKED.value)

    if await glob.LOCK.is_write_locked(glob.LOCK.SpecialValues.SCENE_NAME,
                                       glob.LOCK.SpecialValues.SERVER_NAME):
        raise Arcor2Exception("Scene locked.")

    if await glob.LOCK.is_write_locked(glob.LOCK.SpecialValues.PROJECT_NAME,
                                       glob.LOCK.SpecialValues.SERVER_NAME):
        raise Arcor2Exception("Project locked.")

    if req.dry_run:
        return

    asyncio.ensure_future(start_scene(scene))
Example #5
0
async def close_scene_cb(req: srpc.s.CloseScene.Request, ui: WsClient) -> None:
    """Closes scene on the server.

    :param req:
    :return:
    """

    async with ctx_write_lock(glob.LOCK.SpecialValues.SCENE_NAME,
                              glob.USERS.user_name(ui),
                              dry_run=req.dry_run):

        scene = glob.LOCK.scene_or_exception()

        if glob.LOCK.project:
            raise Arcor2Exception("Project has to be closed first.")

        if not req.args.force and scene.has_changes:
            raise Arcor2Exception("Scene has unsaved changes.")

        can_modify_scene()  # can't close scene while started

        if await glob.LOCK.get_locked_roots_count() > 1:
            raise LockingException(
                glob.LOCK.ErrMessages.SOMETHING_LOCKED.value)

        if req.dry_run:
            return None

        scene_id = scene.id
        glob.LOCK.scene = None
        glob.OBJECTS_WITH_UPDATED_POSE.clear()
        asyncio.ensure_future(notify_scene_closed(scene_id))
Example #6
0
async def ensure_locked(obj_id: str,
                        ui: WsClient,
                        locked_tree: bool = False) -> None:
    """Check if object is write locked.

    Read lock check not needed yet.
    """

    if not await glob.LOCK.is_write_locked(obj_id, glob.USERS.user_name(ui),
                                           locked_tree):
        raise LockingException(glob.LOCK.ErrMessages.NOT_LOCKED.value)
Example #7
0
    async def update_lock(self, obj_id: str, owner: str,
                          upgrade_type: UpdateType) -> None:
        """Upgrades lock to locked whole tree or downgrades lock to simple
        object lock.

        :param obj_id: objects which is locked and updated
        :param owner: owner of current lock
        :param upgrade_type: one of available type
        """

        root_id = await self.get_root_id(obj_id)

        async with self._lock:
            if root_id not in self._locked_objects:
                raise LockingException(self.ErrMessages.NOT_LOCKED.value)

            lock_record = self._get_lock_record(root_id)
            if upgrade_type == UpdateType.TREE:
                lock_record.check_upgrade(obj_id, owner)
                lock_record.tree = True

                to_notify = self.get_all_children(root_id)
                to_notify.add(root_id)
                to_notify.remove(obj_id)
                evt = LockEventData(to_notify, owner, True)

                self._upsert_user_locked_objects(owner, to_notify)
            elif upgrade_type == UpdateType.OBJECT:
                lock_record.check_downgrade(obj_id, owner)
                lock_record.tree = False

                to_notify = self.get_all_children(root_id)
                to_notify.add(root_id)
                to_notify -= {obj_id}
                evt = LockEventData(to_notify, owner)

                self._remove_user_locked_objects(owner, to_notify)
            else:
                raise Arcor2Exception("Unknown type of lock upgrade")

            self.notifications_q.put_nowait(evt)