Repository: apify/crawlee-python
File: src/crawlee/storages/_storage_instance_manager.py (Python)

Code before:
                name=name,
                alias=alias,
                storage_client_cache_key=storage_client_cache_key,
            ):
                return cached_instance

            # Check for conflicts between named and alias storages
            self._check_name_alias_conflict(
                cls,
                name=name,
                alias=alias,
                storage_client_cache_key=storage_client_cache_key,
            )

            # Validate storage name
            if name is not None:
                validate_storage_name(name)

            # Acquire lock for this opener
            opener_lock_key = (cls, str(id or name or alias), storage_client_cache_key)
            if not (lock := self._opener_locks.get(opener_lock_key)):
                lock = Lock()
                self._opener_locks[opener_lock_key] = lock

            async with lock:
                # Re-check cache inside the lock
                if cached_instance := self._get_from_cache(
                    cls,
                    id=id,
                    name=name,
                    alias=alias,
                    storage_client_cache_key=storage_client_cache_key,
                ):
                    return cached_instance

                # Re-check for conflicts between named and alias storages
                self._check_name_alias_conflict(
                    cls,
                    name=name,
                    alias=alias,
                    storage_client_cache_key=storage_client_cache_key,
                )

                # Create new instance
                client: KeyValueStoreClient | DatasetClient | RequestQueueClient
                client = await client_opener_coro

                metadata = await client.get_metadata()

                instance = cls(client, metadata.id, metadata.name)  # type: ignore[call-arg]
                instance_name = getattr(instance, 'name', None)

Review comment (suggestion):
```suggestion
                # Another task could have created the storage while we were waiting for the lock - check if that happened
```

Code after:
                name=name,
                alias=alias,
                storage_client_cache_key=storage_client_cache_key,
            ):
                return cached_instance

            # Validate storage name
            if name is not None:
                validate_storage_name(name)

            # Acquire lock for this opener
            opener_lock_key = (cls, str(id or name or alias), storage_client_cache_key)
            if not (lock := self._opener_locks.get(opener_lock_key)):
                lock = Lock()
                self._opener_locks[opener_lock_key] = lock

            async with lock:
                # Another task could have created the storage while we were waiting for the lock - check if that
                # happened
                if cached_instance := self._get_from_cache(
                    cls,
                    id=id,
                    name=name,
                    alias=alias,
                    storage_client_cache_key=storage_client_cache_key,
                ):
                    return cached_instance

                # Check for conflicts between named and alias storages
                self._check_name_alias_conflict(
                    cls,
                    name=name,
                    alias=alias,
                    storage_client_cache_key=storage_client_cache_key,
                )

                # Create new instance
                client: KeyValueStoreClient | DatasetClient | RequestQueueClient
                client = await client_opener_coro

                metadata = await client.get_metadata()

                instance = cls(client, metadata.id, metadata.name)  # type: ignore[call-arg]
                instance_name = getattr(instance, 'name', None)

                # Cache the instance.
                # Note: No awaits in this section. All cache entries must be written
                # atomically to ensure pre-checks outside the lock see consistent state.

                # Always cache by id.
                self._cache.by_id[cls][instance.id][storage_client_cache_key] = instance