def push(self, stream, reading):
        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 (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:
                if walker.selector.output == output_buffer:
                    walker.notify_added(stream)
        for selector in self._monitors:
            if selector is None or selector.matches(stream):
                for callback in self._monitors[selector]:
                    callback(stream, reading)
        for walker in self._virtual_walkers:
            if walker.matches(stream):
                walker.push(stream, reading)
        self._last_values[stream] = reading