Repository: redis/redis-py
File: redis/commands/core.py (Python)

Code before:
            pieces.append(b"BLOCK")
            pieces.append(str(block))
        if noack:
            pieces.append(b"NOACK")
        if claim_min_idle_time is not None:
            if not isinstance(claim_min_idle_time, int) or claim_min_idle_time < 0:
                raise DataError(
                    "XREADGROUP claim_min_idle_time must be a non-negative integer"
                )
            pieces.append(b"CLAIM")
            pieces.append(claim_min_idle_time)
            options["claim_min_idle_time"] = claim_min_idle_time
        if not isinstance(streams, dict) or len(streams) == 0:
            raise DataError("XREADGROUP streams must be a non empty dict")
        pieces.append(b"STREAMS")
        pieces.extend(streams.keys())
        pieces.extend(streams.values())
        response = self.execute_command("XREADGROUP", *pieces, **options)

        if inspect.iscoroutine(response):
            # Async client - wrap in coroutine that awaits and records
            async def _record_and_return():
                actual_response = await response
                from redis.asyncio.observability.recorder import (
                    record_streaming_lag_from_response as async_record_streaming_lag,
                )

                await async_record_streaming_lag(
                    response=actual_response,
                    consumer_group=groupname,
                    consumer_name=consumername,
                )
                return actual_response

            return _record_and_return()
        else:
            # Sync client
            record_streaming_lag_from_response(
                response=response,
                consumer_group=groupname,
                consumer_name=consumername,
            )
            return response

    def xrevrange(
        self,
        name: KeyT,
        max: StreamIdT = "+",
        min: StreamIdT = "-",
        count: Optional[int] = None,
    ) -> ResponseT:

Review comment (performance):
Importing the async recorder inside the function could have performance implications since this function may be called frequently. Consider importing it at the module level similar to the sync version, or use a conditional import at the top of the file to avoid repeated imports on each function call.

Code after:
            pieces.append(str(block))
        if noack:
            pieces.append(b"NOACK")
        if claim_min_idle_time is not None:
            if not isinstance(claim_min_idle_time, int) or claim_min_idle_time < 0:
                raise DataError(
                    "XREADGROUP claim_min_idle_time must be a non-negative integer"
                )
            pieces.append(b"CLAIM")
            pieces.append(claim_min_idle_time)
            options["claim_min_idle_time"] = claim_min_idle_time
        if not isinstance(streams, dict) or len(streams) == 0:
            raise DataError("XREADGROUP streams must be a non empty dict")
        pieces.append(b"STREAMS")
        pieces.extend(streams.keys())
        pieces.extend(streams.values())
        response = self.execute_command("XREADGROUP", *pieces, **options)

        if inspect.iscoroutine(response):
            # Async client - wrap in coroutine that awaits and records
            async def _record_and_return():
                actual_response = await response

                await async_record_streaming_lag(
                    response=actual_response,
                    consumer_group=groupname,
                    consumer_name=consumername,
                )
                return actual_response

            return _record_and_return()
        else:
            # Sync client
            record_streaming_lag_from_response(
                response=response,
                consumer_group=groupname,
                consumer_name=consumername,
            )
            return response

    def xrevrange(
        self,
        name: KeyT,
        max: StreamIdT = "+",
        min: StreamIdT = "-",
        count: Optional[int] = None,
    ) -> ResponseT:
        """
        Read stream values within an interval, in reverse order.

        name: name of the stream