Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Storage]: Improvement idea for StorageWrapper to allow calling register with client-creating-closure or separate registerClosure

Open
#9,725 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
65/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Active
Tech stack
php
Domain
backend, cloud

Research direction

The issue is about the StorageWrapper class in the Google Cloud PHP library. Look at the StreamWrapper class to understand how client registration works. The proposed changes involve adding a static property for client closures and modifying getClient and unregister methods. Start by examining the existing register method and the stream wrapper registration logic. The goal is to allow lazy initialization of the StorageClient only when a gs:// path is accessed.

Written by the indexing model from the issue text.

Description

Main problem/friction we are having right now is that we have some parts of code that use file accesses via gs://bucketname/path/filename
Due to this in the overall init code for entire application we call

StreamWrapper::register(new StorageClient($config), 'gs');

At the same time we have plenty of API call paths that do not interact with the google storage at all but some flow still may trigger it.
Due to this we are instantiating the client and loading lots of classes without actual need (only 100% confirmed at end of API request).

By adding something like:

  private static $clientClosures = [];

  public static function registerLazyClosure(\Closure $clientClosure, $protocol = null)
  {
    $protocol = $protocol ?: self::DEFAULT_PROTOCOL;
    if (!in_array($protocol, stream_get_wrappers())) {
      if (!stream_wrapper_register($protocol, self::class, STREAM_IS_URL)) {
        throw new \RuntimeException("Failed to register '$protocol://' protocol");
      }
      self::$clientClosures[$protocol] = $clientClosure;
      return true;
    }
    return false;
  }

and changing getClient and unregister to:

  public static function getClient($protocol = null)
  {
    $protocol = $protocol ?: self::DEFAULT_PROTOCOL;
    if (isset(self::$clientClosures[$protocol])) {
      self::$clients[$protocol] = self::$clientClosures[$protocol]();
      unset(self::$clientClosures[$protocol]);
    }
    return self::$clients[$protocol];
  }

  public static function unregister($protocol = null)
  {
    $protocol = $protocol ?: self::DEFAULT_PROTOCOL;
    stream_wrapper_unregister($protocol);
    unset(self::$clients[$protocol], self::$clientClosures[$protocol]);
  }

it would be possible to register a closure that will be executed only when any gs://bucketname/path/filename path is actually accessed and not before.

This became evident when using profiler mode in our deployment for simple ping/pong API endpoint and tracking what parts of code consume unneeded overhead.

In PHP 8.4+ it will be possible to use lazy ghost or proxy objects, but we are still stuck at 8.3 for a while.

Currently we implemented custom-made stream wrapper to achieve that closure-creation approach but possibly would be better to have it natively in the storage library.

Dominant language
PHP
Stars
1.2k
Forks
464
Avg merge
2d 2h
Merged PRs (30d)
103

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from googleapis/google-cloud-php

All issues in googleapis/google-cloud-php

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.