VOOZH about

URL: https://deepwiki.com/hypervel/filesystem/2.3-factory-pattern-and-filesystemmanager

⇱ Factory Pattern and FilesystemManager | hypervel/filesystem | DeepWiki


Loading...
Menu

Factory Pattern and FilesystemManager

Purpose and Scope

This page provides a detailed examination of the Factory pattern implementation in the Hypervel Filesystem package, with the FilesystemManager class serving as the central orchestrator for all filesystem operations. This document covers driver resolution, instance caching, custom driver registration, and the poolable driver mechanism that enables connection pooling for cloud storage backends.

For information about the contracts that define the factory interface, see Contracts and Interfaces. For details about individual driver implementations, see Filesystem Drivers. For connection pooling implementation details, see Object Pooling for Cloud Drivers.


FilesystemManager Overview

The FilesystemManager class src/FilesystemManager.php39-500 is the core factory implementation that manages the lifecycle of all filesystem driver instances. It implements the Factory contract src/FilesystemManager.php39 and serves as a singleton within the Hyperf DI container, ensuring consistent state across all filesystem operations in the application.

Key Responsibilities

ResponsibilityMethodsPurpose
Driver Resolutiondisk(), drive(), cloud()Resolve and return filesystem instances by name
Instance Cachingget(), set(), forgetDisk(), purge()Cache resolved drivers to avoid redundant instantiation
Driver Creationresolve(), createLocalDriver(), createS3Driver(), etc.Create specific driver instances with proper configuration
Custom Driversextend(), customCreatorsRegister and manage user-defined driver implementations
Pooling Supportpoolables, createPoolProxy()Wrap cloud drivers in connection pool proxies
ConfigurationgetConfig(), getDefaultDriver(), getDefaultCloudDriver()Retrieve driver configurations from the container

Sources: src/FilesystemManager.php39-500


Factory Pattern Architecture


Diagram: FilesystemManager Factory Architecture

This diagram shows the complete factory architecture. The FilesystemManager implements the Factory contract and maintains three critical internal state arrays: disks for caching instances, customCreators for user-registered drivers, and poolables for drivers that support connection pooling. The public API provides multiple entry points (disk(), drive(), cloud(), build()), all of which flow through the internal resolution mechanism. Helper factories (FilesystemFactory and CloudStorageFactory) delegate to the manager for actual instance creation.

Sources: src/FilesystemManager.php39-500 src/FilesystemFactory.php1-18 src/CloudStorageFactory.php1-18


Driver Resolution Process

The driver resolution process is the core mechanism by which the FilesystemManager converts a disk name into a concrete filesystem instance.

Resolution Flow


Diagram: Driver Resolution Sequence

This sequence diagram illustrates the complete resolution flow. The manager first checks the cache for an existing instance. On a cache miss, it retrieves configuration, determines the driver type (custom vs built-in), checks if the driver should be pooled, creates the appropriate instance, caches it, and returns it to the caller.

Sources: src/FilesystemManager.php82-161

Resolution Method Details

The resolve() method src/FilesystemManager.php124-161 implements the core resolution logic:


Diagram: Driver Resolution Logic Flowchart

This flowchart details the decision tree within the resolve() method. The method first validates that a driver is configured, then checks for custom creators, validates method existence for built-in drivers, and finally determines whether to wrap the instance in a pool proxy based on the poolables array.

Sources: src/FilesystemManager.php124-161

Configuration Retrieval

The manager retrieves configuration from the Hyperf configuration system through three key methods:

MethodPathDefaultPurpose
getConfig(name)filesystems.disks.{name}[]Get configuration for a specific disk
getDefaultDriver()filesystems.default(none)Get the default disk name
getDefaultCloudDriver()filesystems.cloud's3'Get the default cloud disk name

Sources: src/FilesystemManager.php417-439


Instance Caching Strategy

The FilesystemManager maintains a disks array src/FilesystemManager.php46 that caches resolved filesystem instances. This caching strategy is critical for performance in long-running applications like Hyperf.

Cache Operations


Diagram: Instance Caching Architecture

The caching mechanism uses a simple associative array where keys are disk names and values are filesystem instances. The get() method checks the cache before resolving, while set() stores instances after creation. The forgetDisk() and purge() methods allow manual cache invalidation.

Sources: src/FilesystemManager.php46 src/FilesystemManager.php82-117 src/FilesystemManager.php403-463

Cache Behavior

ScenarioMethodCache InteractionBehavior
First Accessdisk('s3')Read miss, WriteResolves driver, stores in cache, returns instance
Subsequent Accessdisk('s3')Read hitReturns cached instance immediately
On-Demand Buildbuild(config)No cacheAlways creates new instance (name is 'ondemand')
Manual Purgepurge('s3')DeleteRemoves from cache, next access will re-resolve
Manual ForgetforgetDisk(['s3', 'gcs'])DeleteRemoves multiple disks from cache

The disk() method src/FilesystemManager.php82-87 always writes to the cache, even when returning a cached instance: return $this->disks[$name] = $this->get($name);. This pattern ensures the cache is always up-to-date.

Sources: src/FilesystemManager.php82-117 src/FilesystemManager.php446-463


Built-in Driver Creators

The FilesystemManager includes factory methods for creating each supported driver type. These methods follow a naming convention: create{Driver}Driver(array $config, ?string $name).

Driver Creator Methods

MethodDriver TypeReturnsPoolableConfiguration Keys
createLocalDriver()Local filesystemLocalFilesystemAdapterNoroot, permissions, visibility, links, lock, serve
createS3Driver()AWS S3AwsS3V3AdapterYeskey, secret, region, bucket, root, version, endpoint, use_path_style_endpoint
createGcsDriver()Google Cloud StorageGoogleCloudStorageAdapterYeskeyFilePath, keyFile, projectId, bucket, root, apiEndpoint
createFtpDriver()FTPFilesystemAdapterNohost, port, username, password, root, passive, ssl, timeout
createSftpDriver()SFTPFilesystemAdapterNohost, username, password, privateKey, root, port, timeout, permissions
createScopedDriver()Scoped diskFilesystemAdapterDepends on parentdisk, prefix, visibility

Sources: src/FilesystemManager.php174-375

Local Driver Creation

The createLocalDriver() method src/FilesystemManager.php174-202 demonstrates the typical driver creation pattern:

  1. Visibility Configuration: Constructs a PortableVisibilityConverter from permissions configuration src/FilesystemManager.php176-179
  2. Link Handling: Determines symbolic link behavior (SKIP_LINKS or DISALLOW_LINKS) src/FilesystemManager.php181-183
  3. Adapter Creation: Instantiates the League Flysystem LocalAdapter src/FilesystemManager.php185-190
  4. Wrapper Creation: Creates a LocalFilesystemAdapter wrapping the Flysystem adapter src/FilesystemManager.php192-196
  5. Additional Configuration: Sets disk name and signed URL serving options src/FilesystemManager.php196-201

Sources: src/FilesystemManager.php174-202

Cloud Driver Creation

Cloud drivers (S3 and GCS) follow a similar pattern but include additional steps for SDK client instantiation and credential handling.

The createS3Driver() method src/FilesystemManager.php242-264:

  1. Format Configuration: Converts configuration to AWS SDK format via formatS3Config() src/FilesystemManager.php244
  2. Client Creation: Instantiates S3Client with credentials src/FilesystemManager.php254
  3. Visibility Setup: Creates AWS-specific visibility converter src/FilesystemManager.php248-250
  4. Adapter Creation: Creates S3Adapter with client, bucket, and options src/FilesystemManager.php256
  5. Wrapper Creation: Returns AwsS3V3Adapter with Flysystem instance src/FilesystemManager.php258-263

The formatS3Config() method src/FilesystemManager.php269-282 handles credential consolidation, converting separate key, secret, and token values into the credentials array expected by the AWS SDK.

Sources: src/FilesystemManager.php242-282

Flysystem Instance Creation

All driver creators use the createFlysystem() method src/FilesystemManager.php380-400 to instantiate the League Flysystem Filesystem instance. This method applies cross-cutting concerns:


Diagram: Flysystem Instance Creation with Decorators

This method demonstrates the Decorator pattern, wrapping the base adapter with optional functionality layers (read-only, path prefixing) before creating the Flysystem instance. The configuration is filtered to pass only relevant keys to Flysystem src/FilesystemManager.php392-399

Sources: src/FilesystemManager.php380-400


Custom Driver Registration

The extend() method src/FilesystemManager.php470-479 allows developers to register custom driver implementations at runtime. This extensibility mechanism enables support for additional storage backends without modifying the core package.

Extension Mechanism


Diagram: Custom Driver Registration and Resolution

When extend() is called, the driver name and callback are stored in customCreators. If the poolable parameter is true, the driver is also added to the poolables array. During resolution, custom creators take precedence over built-in drivers.

Sources: src/FilesystemManager.php470-479

Custom Creator Callback

The callback registered via extend() receives two parameters src/FilesystemManager.php168:

  1. $app: The DI container (ContainerInterface), allowing access to services
  2. $config: The disk configuration array from filesystems.php

The callback must return an instance implementing the Filesystem contract (or Cloud for cloud drivers).

Registration and Usage Example Pattern


Diagram: Custom Driver Lifecycle

Custom drivers are registered during application bootstrap (typically in a service provider) and resolved lazily when first accessed. The creator callback is invoked only once per disk name; subsequent accesses return the cached instance.

Sources: src/FilesystemManager.php164-169 src/FilesystemManager.php470-479


Poolable Driver Support

The poolables array src/FilesystemManager.php61 defines which drivers should be wrapped in a FilesystemPoolProxy for connection pooling. By default, this includes 's3' and 'gcs', the two cloud storage drivers that benefit most from pooling in high-concurrency environments.

Pooling Decision Logic


Diagram: Pooling Decision Tree

During resolution, the manager checks if the driver type exists in the poolables array. If so, it calls createPoolProxy() instead of returning the driver directly. The createPoolProxy() method is provided by the HasPoolProxy trait src/FilesystemManager.php41 from the hypervel/object-pool package.

Sources: src/FilesystemManager.php61 src/FilesystemManager.php124-161

Pool Configuration

Pool configuration is specified in the disk's configuration array under the pool key. The resolve() method passes this configuration to createPoolProxy() src/FilesystemManager.php140-156:


The pool configuration supports keys such as min_objects, max_objects, wait_timeout, and max_idle_time. For detailed information about these options, see Object Pooling for Cloud Drivers.

Sources: src/FilesystemManager.php136-157

Adding Custom Poolable Drivers

When registering a custom driver via extend(), the third parameter controls whether the driver should be poolable src/FilesystemManager.php470:


Setting poolable to true adds the driver name to the poolables array via the addPoolable() method inherited from HasPoolProxy.

Sources: src/FilesystemManager.php470-479


Helper Factory Classes

The package provides two helper factory classes that integrate with Hyperf's DI container: FilesystemFactory and CloudStorageFactory. These classes are registered in the DI container and provide simplified access to filesystem instances.

Factory Helper Architecture


Diagram: Helper Factory Integration

The helper factories act as adapters between the DI container's contract-based injection system and the FilesystemManager. When an application requests a Filesystem or Cloud instance via dependency injection, the container invokes the appropriate factory helper, which delegates to the manager.

Sources: src/FilesystemFactory.php1-18 src/CloudStorageFactory.php1-18

FilesystemFactory

The FilesystemFactory class src/FilesystemFactory.php11-18 is an invokable class that returns the default filesystem disk:


This factory retrieves the FilesystemManager from the container (via the Factory contract) and calls disk() without arguments, which returns the default disk as configured in filesystems.default.

Sources: src/FilesystemFactory.php11-18

CloudStorageFactory

The CloudStorageFactory class src/CloudStorageFactory.php11-18 similarly provides access to the default cloud storage:


Note that this factory calls cloud() with CloudContract::class as an argument src/CloudStorageFactory.php16 though the cloud() method in FilesystemManager src/FilesystemManager.php92-98 ignores this parameter and uses the configured default cloud driver.

Sources: src/CloudStorageFactory.php11-18

Usage via Dependency Injection

These helper factories enable clean dependency injection in application code:

Inject ThisResolves ToManager Method Called
Factory contractFilesystemManager(direct instance)
Filesystem contractDefault disk instancedisk()
Cloud contractDefault cloud instancecloud()

This pattern allows application code to declare explicit dependencies on filesystem contracts without directly coupling to the FilesystemManager.

Sources: src/FilesystemFactory.php1-18 src/CloudStorageFactory.php1-18


On-Demand Disk Creation

The build() method src/FilesystemManager.php103-109 provides a mechanism for creating filesystem instances without pre-configured disk names. This is useful for dynamically generated storage configurations or temporary storage locations.

Build Method Behavior

The build() method accepts either a configuration array or a string (interpreted as a local filesystem root path):


When passed a string, it automatically creates a local driver configuration with that string as the root path src/FilesystemManager.php105-108

Key characteristics:

  • Uses the fixed name 'ondemand' for resolution src/FilesystemManager.php105
  • Bypasses the normal cache lookup (since resolve() is called directly)
  • Can be called multiple times with different configurations
  • Each call creates a new instance (no caching by configuration)

Sources: src/FilesystemManager.php103-109

Scoped Driver Support

The createScopedDriver() method src/FilesystemManager.php356-375 provides another form of on-demand disk creation. It creates a new disk instance based on an existing disk but with a path prefix applied:

  1. Validation: Requires both disk and prefix in configuration src/FilesystemManager.php358-363
  2. Parent Resolution: Retrieves the parent disk's configuration src/FilesystemManager.php366
  3. Configuration Merging: Adds the prefix to the parent configuration src/FilesystemManager.php368
  4. Instance Creation: Calls build() with the merged configuration src/FilesystemManager.php365-374

The scoped driver mechanism allows multiple logical disks to share the same underlying storage but operate in different subdirectories, useful for multi-tenant applications or organized data segregation.

Sources: src/FilesystemManager.php356-375


Manager Lifecycle Methods

The FilesystemManager provides several methods for managing the lifecycle of disk instances and the manager itself.

Disk Management Methods

MethodParametersPurposeBehavior
set()string $name, mixed $diskManually set a disk instanceAdds or replaces entry in disks cache
forgetDisk()array|string $diskRemove disk(s) from cacheUnsets cache entries, does not close connections
purge()?string $name = nullDisconnect and remove diskUnsets cache entry for specified or default disk

Sources: src/FilesystemManager.php403-463

Application Instance Management

The setApplication() method src/FilesystemManager.php484-489 allows the DI container reference to be changed after instantiation:


This method is primarily used in testing scenarios or during application lifecycle transitions. In normal operation, the container is injected via the constructor src/FilesystemManager.php66-69 and remains constant.

Sources: src/FilesystemManager.php484-489

Magic Method Delegation

The __call() magic method src/FilesystemManager.php496-499 allows the manager to proxy method calls to the default disk:


This enables calling filesystem operations directly on the manager instance without explicitly retrieving a disk. The @mixin annotations src/FilesystemManager.php36-37 provide IDE autocomplete support for this delegation pattern.

Sources: src/FilesystemManager.php36-499


Configuration Retrieval Pattern

The FilesystemManager retrieves all configuration from the Hyperf ConfigInterface service through a consistent pattern.

Configuration Structure


Diagram: Configuration Access Pattern

All configuration access flows through the ConfigInterface service, which reads from the filesystems.php configuration file. The manager provides three specialized methods for retrieving different aspects of the configuration.

Sources: src/FilesystemManager.php417-439

Configuration Methods Implementation

Each configuration method delegates to ConfigInterface::get() with a specific key path:

getConfig(string $name) src/FilesystemManager.php417-421:


Returns an array of configuration options for the named disk, or an empty array if not configured.

getDefaultDriver() src/FilesystemManager.php426-430:


Returns the string name of the default disk, used when disk() is called without arguments.

getDefaultCloudDriver() src/FilesystemManager.php435-439:


Returns the string name of the default cloud disk, defaulting to 's3' if not configured.

Sources: src/FilesystemManager.php417-439

Refresh this wiki

On this page