code: def push(self, stream, reading):
          
  
          # Make sure the stream is correct
          reading = copy.copy(reading)
          reading.stream = stream.encode()
  
          if stream.buffered:
              output_buffer = stream.output
  
              if self.id_assigner is not None:
                  reading.reading_id = self.id_assigner(stream, reading)
  
              try:
                  self._engine.push(reading)
              except StorageFullError:
                  # If we are in fill-stop mode, don't auto erase old data.
                  if (stream.output and not self._rollover_streaming) or (not stream.output and not self._rollover_storage):
                      raise
  
                  self._erase_buffer(stream.output)
                  self._engine.push(reading)
  
              for walker in self._queue_walkers:
                  # Only notify the walkers that are on this queue
                  if walker.selector.output == output_buffer:
                      walker.notify_added(stream)
  
          # Activate any monitors we have for this stream
          for selector in self._monitors:
              if selector is None or selector.matches(stream):
                  for callback in self._monitors[selector]:
                      callback(stream, reading)
  
          # Virtual streams live only in their walkers, so update each walker
          # that contains this stream.
          for walker in self._virtual_walkers:
              if walker.matches(stream):
                  walker.push(stream, reading)
  
          self._last_values[stream] = reading
docs: Push a reading into a stream, updating any associated stream walkers.
  
          Args:
              stream (DataStream): the stream to push the reading into
              reading (IOTileReading): the reading to push