

from twisted.internet import defer


class Serializer(object):

    def __init__(self):
        self._lock = defer.DeferredLock()
        self._waiting = {}

    def call(self, func, args=(), kwargs=None, collapsible=False):
        d = self._lock.acquire()
        self._waiting[d] = collapsible
        if not kwargs:
            kwargs = {}
        @d.addCallback
        def _locked(_):
            if collapsible and len(self._waiting) > 1:
                # Superseded
                return
            return func(*args, **kwargs)
        @d.addBoth
        def _unlock(result):
            self._lock.release()
            del self._waiting[d]
            return result
        return d



from twisted.internet import defer


class Serializer(object):

    def __init__(self):
        self._lock = defer.DeferredLock()
        self._waiting = {}

    def call(self, func, args=(), kwargs=None, collapsible=False):
        d = self._lock.acquire()
        self._waiting[d] = collapsible
        if not kwargs:
            kwargs = {}
        @d.addCallback
        def _locked(_):
            if collapsible and len(self._waiting) > 1:
                # Superseded
                return
            return func(*args, **kwargs)
        @d.addBoth
        def _unlock(result):
            del self._waiting[d]
            self._lock.release()
            return result
        return d

Fix Serializer locking bug that caused it to skip calls it should have made
Fix Serializer locking bug that caused it to skip calls it should have made

  
  
  from twisted.internet import defer
  
  
  class Serializer(object):
  
      def __init__(self):
          self._lock = defer.DeferredLock()
          self._waiting = {}
  
      def call(self, func, args=(), kwargs=None, collapsible=False):
          d = self._lock.acquire()
          self._waiting[d] = collapsible
          if not kwargs:
              kwargs = {}
          @d.addCallback
          def _locked(_):
              if collapsible and len(self._waiting) > 1:
                  # Superseded
                  return
              return func(*args, **kwargs)
          @d.addBoth
          def _unlock(result):
+             del self._waiting[d]
              self._lock.release()
-             del self._waiting[d]
              return result
          return d
  
Fix Serializer locking bug that caused it to skip calls it should have made
## Code Before:


from twisted.internet import defer


class Serializer(object):

    def __init__(self):
        self._lock = defer.DeferredLock()
        self._waiting = {}

    def call(self, func, args=(), kwargs=None, collapsible=False):
        d = self._lock.acquire()
        self._waiting[d] = collapsible
        if not kwargs:
            kwargs = {}
        @d.addCallback
        def _locked(_):
            if collapsible and len(self._waiting) > 1:
                # Superseded
                return
            return func(*args, **kwargs)
        @d.addBoth
        def _unlock(result):
            self._lock.release()
            del self._waiting[d]
            return result
        return d

## Instruction:
Fix Serializer locking bug that caused it to skip calls it should have made
## Code After:


from twisted.internet import defer


class Serializer(object):

    def __init__(self):
        self._lock = defer.DeferredLock()
        self._waiting = {}

    def call(self, func, args=(), kwargs=None, collapsible=False):
        d = self._lock.acquire()
        self._waiting[d] = collapsible
        if not kwargs:
            kwargs = {}
        @d.addCallback
        def _locked(_):
            if collapsible and len(self._waiting) > 1:
                # Superseded
                return
            return func(*args, **kwargs)
        @d.addBoth
        def _unlock(result):
            del self._waiting[d]
            self._lock.release()
            return result
        return d
