code: def drain(self, sid=None):
          
          if self.is_draining:
              return
  
          if self.is_closed:
              raise ErrConnectionClosed
  
          if self.is_connecting or self.is_reconnecting:
              raise ErrConnectionReconnecting
  
          # Drain a single subscription
          if sid is not None:
              raise tornado.gen.Return(self._drain_sub(sid))
  
          # Start draining the subscriptions
          self._status = Client.DRAINING_SUBS
  
          drain_tasks = []
          for ssid, sub in self._subs.items():
              task = self._drain_sub(ssid)
              drain_tasks.append(task)
  
          # Wait for subscriptions to stop handling messages.
          drain_is_done = tornado.gen.multi(drain_tasks)
          try:
              yield tornado.gen.with_timeout(
                  timedelta(seconds=self.options["drain_timeout"]),
                  drain_is_done,
                  )
          except tornado.gen.TimeoutError:
              if self._error_cb is not None:
                  yield self._error_cb(ErrDrainTimeout())
          finally:
              self._status = Client.DRAINING_PUBS
              yield self.flush()
              yield self.close()
docs: Drain will put a connection into a drain state. All subscriptions will
          immediately be put into a drain state. Upon completion, the publishers
          will be drained and can not publish any additional messages. Upon draining
          of the publishers, the connection will be closed. Use the `closed_cb'
          option to know when the connection has moved from draining to closed.
  
          If a sid is passed, just the subscription with that sid will be drained
          without closing the connection.