Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Etcd Php Laravel Package

start-point/etcd-php

PHP client for etcd v3 with a simple API for KV operations, leases, and authentication/roles/users. Install via Composer and connect to an etcd endpoint to put/get/delete keys, query prefixes, manage leases, and handle auth tokens.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require start-point/etcd-php
    
  2. Initialize the client in a Laravel service provider (e.g., AppServiceProvider):
    use Etcd\Client;
    
    public function register()
    {
        $this->app->singleton(Client::class, function ($app) {
            return new Client(config('etcd.host'), config('etcd.port'));
        });
    }
    
  3. Configure Etcd connection in config/services.php:
    'etcd' => [
        'host' => env('ETCD_HOST', '127.0.0.1'),
        'port' => env('ETCD_PORT', 2379),
        'timeout' => 2.0, // Optional: connection timeout in seconds
    ],
    
  4. First use case: Fetch a dynamic configuration value:
    $client = app(Client::class);
    $redisHost = $client->get('config/redis/host');
    

Where to Look First

  • Key-Value Operations: Start with put(), get(), and del() for basic configuration management.
  • Leases: Use grant() and keepAlive() for distributed locks or ephemeral data.
  • Authentication: Enable authEnable() and authenticate() if Etcd requires RBAC.
  • Documentation: Refer to the wiki for advanced use cases like watchers or transactions (if supported).

Implementation Patterns

Core Workflows

1. Dynamic Configuration Management

  • Pattern: Replace static Laravel configs with Etcd-backed values.
  • Example:
    // In a service provider
    public function boot()
    {
        $client = app(Client::class);
        config(['database.connections.etcd.host' => $client->get('config/database/host')]);
    }
    
  • Watch for Changes:
    // Note: Watch functionality may not be fully supported in this package.
    // Use polling as a fallback:
    $lastVersion = null;
    while (true) {
        $value = $client->get('config/feature_flags/enabled', ['version' => $lastVersion]);
        if ($value['version'] !== $lastVersion) {
            $lastVersion = $value['version'];
            // Update feature flags in Laravel
        }
        sleep(1); // Poll every second
    }
    

2. Service Discovery

  • Pattern: Register and discover Laravel services (e.g., queues, APIs) in Etcd.
  • Example:
    // Register a service
    $client->put('/services/api/v1', json_encode([
        'host' => '10.0.0.1',
        'port' => 8000,
        'status' => 'healthy',
    ]));
    
    // Discover services
    $services = $client->getKeysWithPrefix('/services/');
    $apiService = json_decode($client->get('/services/api/v1'), true);
    

3. Distributed Locking with Leases

  • Pattern: Use leases to implement distributed locks for critical sections (e.g., cron jobs, database migrations).
  • Example:
    $client = app(Client::class);
    $leaseId = $client->grant(10); // 10-second lease
    
    try {
        // Acquire lock by setting a key with the lease
        $client->put('/locks/migration', 'locked', ['lease' => $leaseId]);
    
        // Critical section
        $this->runMigration();
    
    } finally {
        // Release lock by deleting the key
        $client->del('/locks/migration');
        $client->revoke($leaseId);
    }
    

4. Authentication and RBAC

  • Pattern: Secure Etcd access for multi-tenant Laravel applications.
  • Example:
    $client = app(Client::class);
    $client->authEnable();
    $token = $client->authenticate('admin', 'securepassword');
    $client->setToken($token);
    
    // Grant permissions to a role
    $client->grantRolePermission('admin', Client::PERMISSION_READWRITE, '/config/*');
    

Laravel-Specific Integrations

1. Custom Cache Store

Extend Laravel’s cache system to use Etcd:

use Illuminate\Contracts\Cache\Store;

class EtcdCacheStore implements Store {
    protected $client;

    public function __construct(Client $client) {
        $this->client = $client;
    }

    public function get($key, $default = null) {
        $value = $this->client->get("cache/{$key}");
        return $value ? json_decode($value, true) : $default;
    }

    public function put($key, $value, $seconds) {
        $this->client->put("cache/{$key}", json_encode($value), [
            'lease' => $this->client->grant($seconds)
        ]);
    }

    // Implement other cache methods...
}

Register in config/cache.php:

'etcd' => [
    'driver' => 'etcd',
    'key' => env('CACHE_ETCD_KEY', 'default'),
],

2. Dynamic Config Repository

Create a facade for Etcd-backed configs:

// app/Facades/EtcdConfig.php
namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class EtcdConfig extends Facade {
    protected static function getFacadeAccessor() {
        return 'etcd.config';
    }
}

Bind in AppServiceProvider:

$this->app->bind('etcd.config', function ($app) {
    return new class($app) {
        public function get($key, $default = null) {
            $client = $app['Etcd\Client'];
            $value = $client->get("config/{$key}");
            return $value ? json_decode($value, true) : $default;
        }
    };
});

Usage:

$redisHost = EtcdConfig::get('redis.host');

3. Queue Job Deduplication

Prevent duplicate jobs using Etcd leases:

use Illuminate\Bus\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Etcd\Client;

class ProcessPayment implements ShouldQueue {
    use InteractsWithQueue;

    public function handle() {
        $client = app(Client::class);
        $leaseId = $client->grant(300); // 5-minute lease

        try {
            // Try to acquire lock
            $locked = $client->put('/jobs/process_payment', 'locked', [
                'lease' => $leaseId,
                'prev_kv' => true
            ]);

            if ($locked['prev_kv']) {
                // Another instance is processing; skip
                return;
            }

            // Process payment
            $this->executePayment();

        } finally {
            $client->del('/jobs/process_payment');
            $client->revoke($leaseId);
        }
    }
}

Gotchas and Tips

Pitfalls

  1. Stale Codebase:

    • The package was last updated in 2017 and may not support Etcd v3.5+ features (e.g., watch prefixes, user authentication).
    • Workaround: Test thoroughly against your Etcd version. Fork and extend if missing features are critical.
  2. No Native Watch Support:

    • The package lacks built-in watch functionality for key changes.
    • Workaround: Implement polling or use a separate process to tail Etcd logs (e.g., etcdctl watch).
  3. Authentication Quirks:

    • The authenticate() method may not support all Etcd auth flows (e.g., JWT tokens).
    • Workaround: Use static tokens or implement a custom auth handler.
  4. Lease Management:

    • Leases require manual renewal (keepAlive), which can fail silently.
    • Workaround: Wrap lease operations in a retry loop or use a background job to refresh leases.
  5. Error Handling:

    • The package may not throw exceptions for all Etcd errors (e.g., invalid keys, permission denied).
    • Workaround: Check response statuses manually:
      $response = $client->get('nonexistent_key');
      if (isset($response['error'])) {
          // Handle error
      }
      
  6. Performance Overhead:

    • The HTTP JSON API may introduce latency compared to gRPC.
    • Workaround: Benchmark against alternatives like etcd3 (gRPC-based).
  7. No Transaction Support:

    • The package does not support Etcd’s transactional writes.
    • Workaround: Implement retries with compareAndSwap or use application-level locks.

Debugging Tips

  1. Enable Etcd Logging: Configure Etcd’s logging to debug issues:
    etcd --logger=zap --log-level=DEBUG
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels