Skip to content

Deadlock on Offline Shadow Update #52

Closed
@kc9zyz

Description

@kc9zyz

Preconditions:

  1. Two Device shadows are associated (as in a gateway scenerio), but no update has been sent so the update/accepted and update/rejected topics are not yet subscribed to.

Process to Re-Create:

  1. Remove connectivity from the library
  2. Attempt to update one of the shadows, receive a subscribeTimoutException
  3. Attempt to update the second shadow

Result

The call to update the second shadow never returns. The offending call is here:

def basicShadowSubscribe(self, srcShadowName, srcShadowAction, srcCallback):
        self._shadowSubUnsubOperationLock.acquire()
        currentShadowAction = _shadowAction(srcShadowName, srcShadowAction)
        if currentShadowAction.isDelta:
            self._mqttCoreHandler.subscribe(currentShadowAction.getTopicDelta(), 0, srcCallback)
        else:
            self._mqttCoreHandler.subscribe(currentShadowAction.getTopicAccept(), 0, srcCallback)
            self._mqttCoreHandler.subscribe(currentShadowAction.getTopicReject(), 0, srcCallback)
        time.sleep(2)
        self._shadowSubUnsubOperationLock.release()

On line 68 a lock is acquired. Notice that on lines 71, 73, and 74, a subscribeTimeoutException may be raised (as happened in the second step to recreate), jumping past the lock release call on line 76. Any cases of locks being acquired/released should be using context managers or exception handling to ensure that the lock is released if an operation fails.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions