Skip to main content

Etcd Lock Plugin

github.com/go-lynx/lynx-etcd-lock is Lynx's etcd-backed distributed lock layer. It is a runtime plugin, but it does not ship an independent configuration schema or standalone example_config.yml.

Runtime Facts

ItemValue
Go modulegithub.com/go-lynx/lynx-etcd-lock
Runtime plugin nameetcd.distributed.lock
Plugin metadata config prefixlynx.etcd-lock
Required upstream runtime resourceetcd.config.center
Public APIsSetCallback, Lock, LockWithOptions, LockWithRetry, NewLockFromClient, GetStats(), Shutdown()

Configuration Boundary

  • There is no dedicated lynx-etcd-lock YAML tree in the repository templates.
  • There is no standalone conf schema or conf/example_config.yml for lock-specific YAML.
  • Startup depends on the shared etcd plugin publishing the etcd.config.center runtime resource.
  • If the upstream etcd plugin is missing or does not expose a live client, initialization fails with errors such as etcd config center plugin not found or etcd client is nil.
  • Lock behavior is configured in code through LockOptions, RetryStrategy, and RenewalConfig, not through YAML.

Effective YAML: inherited from lynx.etcd

Because the lock plugin reuses the upstream etcd client, the only YAML that matters is the upstream Etcd configuration.

Inherited lynx.etcd fields

FieldEffect on Etcd LockDefault / interactionCommon misunderstanding
endpointsDecides which etcd cluster the lock plugin talks to.Required by the upstream client.Thinking lock acquisition works without any upstream etcd endpoints.
timeoutAffects shared client operation timeout.Defaults to 10s in upstream plugin.Treating it as lock lease TTL.
dial_timeoutAffects how long the shared client waits to connect.Defaults to 5s.Forgetting that slow connections can fail before any lock call runs.
namespaceNamespaces config reads for the upstream etcd plugin, but does not rename lock keys.Defaults to lynx/config.Assuming it changes the lock storage key prefix.
username / passwordAuthenticate the shared etcd client.Optional.Forgetting them on an authenticated cluster.
enable_tlsEnables TLS for the shared etcd client.Pair with cert/key/CA paths as needed.Expecting secure lock traffic while leaving TLS off.
cert_file / key_file / ca_fileProvide TLS material for the shared client.Used only when cluster TLS mode requires them.Assuming the lock plugin has its own separate TLS settings.
enable_cacheUpstream etcd config-cache toggle.Real upstream gate.Thinking it changes lock semantics. It does not; it only affects config-center behavior.
enable_metricsUpstream etcd metrics toggle.Real upstream gate.Thinking it is a dedicated lock metrics switch.
enable_retry / max_retry_times / retry_intervalControl the upstream etcd plugin retry manager.Real upstream gates/defaults.Confusing upstream client retries with lock acquisition retry policy.
shutdown_timeoutAffects upstream client cleanup window.Fallback 10s upstream.Assuming it is the same as lock renewal or operation timeout.
enable_register / enable_discoveryControl upstream registry/discovery behavior only.Default false.Believing these flags are required for locking. They are not.
registry_namespace / ttlControl upstream service registration only.Upstream defaults lynx/services and 30s.Assuming they define lock key namespace or lock lease duration.
service_config.prefix / additional_prefixesControl upstream config-source loading only.Fallback to upstream namespace and declaration order.Assuming they influence distributed lock storage paths.
enable_graceful_shutdown / enable_logging / log_level / service_config.priority / service_config.merge_strategyCompatibility-only upstream schema fields.Accepted by upstream schema but not active plugin-local toggles.Expecting them to be lock-specific controls.

Complete YAML Example

There is still no standalone lynx.etcd-lock schema. The complete inherited example below is the upstream lynx.etcd configuration that the lock plugin actually consumes.

lynx:
etcd:
endpoints:
- 127.0.0.1:2379 # Required shared etcd endpoint list for the reused client
timeout: 10s # Shared client operation timeout
dial_timeout: 5s # Shared client connection timeout
namespace: lynx/config # Upstream config-key namespace; does not rename lock keys
username: "" # Optional username for authenticated clusters
password: "" # Optional password paired with username
enable_tls: false # Enable TLS for the shared etcd client
cert_file: "" # Client cert path when TLS auth is required
key_file: "" # Client key path when TLS auth is required
ca_file: "" # CA bundle path when server cert validation is required
enable_cache: true # Upstream config-cache behavior only; does not change lock semantics
enable_metrics: true # Upstream etcd metrics switch
enable_retry: true # Upstream client retry manager switch
max_retry_times: 3 # Upstream retry cap
retry_interval: 1s # Upstream retry interval
shutdown_timeout: 10s # Shared client cleanup timeout
enable_register: false # Upstream registry switch only; not needed for locking
enable_discovery: false # Upstream discovery switch only; not needed for locking
registry_namespace: lynx/services # Upstream registry namespace only
ttl: 30s # Upstream service-registration TTL only
service_config:
prefix: lynx/config # Upstream config prefix only
additional_prefixes:
- lynx/config/app # Additional upstream config prefix
# enable_graceful_shutdown: true # Compatibility-only upstream schema field
# enable_logging: true # Compatibility-only upstream schema field
# log_level: info # Compatibility-only upstream schema field
# service_config.priority: 0 # Compatibility-only upstream schema field
# service_config.merge_strategy: override # Compatibility-only upstream schema field

# There is no standalone lynx.etcd-lock schema in the repository.
# Lock behavior is configured in code via LockOptions.

Minimum Viable YAML Example

Etcd Lock inherits its startup configuration from the etcd plugin. There is no separate lynx.etcd-lock YAML tree, so the smallest runnable config is the minimal shared lynx.etcd block below.

lynx:
etcd:
endpoints:
- 127.0.0.1:2379 # Required shared etcd endpoint for lock client reuse

Code-level lock options

LockOptions

FieldRoleUse whenDefault / interactionCommon misconfig
ExpirationLease TTL for one lock acquisition.Always; every lock must have a positive expiration.Default 30s; validation requires > 0.Passing 0 and expecting the lock to live forever.
RetryStrategyRetry policy for acquisition conflicts.When callers should retry after contention.Default MaxRetries: 3, RetryDelay: 100ms.Confusing lock retry policy with upstream etcd client retry policy.
RenewalEnabledEnables background lease renewal after the lock is acquired.When critical sections may outlive one lease TTL.Default true.Leaving it off for long-running business sections and then seeing the lock expire mid-flight.
RenewalThresholdFraction of remaining TTL at which renewal starts.When auto-renew is enabled and you need explicit renewal timing.Default 0.3; validation range 0..1.Using values above 1 or below 0.
WorkerPoolSizeRenewal worker pool capacity.When many locks may auto-renew concurrently.Default 50; must be >= 0.Setting a negative size or assuming 0 means "disable renewal".
RenewalConfigDetailed renewal retry/polling config.When renewal pressure or backoff needs tuning.Uses DefaultRenewalConfig below.Changing top-level retry strategy and expecting renewal retry behavior to match automatically.
OperationTimeoutPer-operation timeout for acquire/release.When each lock call should have a stricter bound than the caller context.Default 600ms; 0 means no separate operation timeout.Treating it as the same thing as Expiration.

RenewalConfig

FieldRoleDefaultCommon misconfig
MaxRetriesRenewal retry attempts.4Setting too low and making renewal brittle under brief etcd jitter.
BaseDelayRenewal backoff base delay.100msSetting too high and starting retries too slowly.
MaxDelayRenewal backoff cap.800msForgetting that large caps can consume too much remaining lease time.
CheckIntervalRenewal polling cadence.300msMaking it longer than your safe renewal window.
OperationTimeoutPer-renewal operation timeout.600msAssuming it changes the lock lease TTL.

Lock key rules

RuleMeaning
Business key must not be emptyValidateKey rejects empty strings.
Business key length must be <= 255Longer keys are rejected before lock creation.
Actual etcd storage key is lynx/lock/<business-key>This prefix is built in code and is not currently configurable through YAML.

Usage Examples

options := etcdlock.DefaultLockOptions
options.Expiration = 30 * time.Second
options.RetryStrategy = etcdlock.RetryStrategy{
MaxRetries: 3,
RetryDelay: 100 * time.Millisecond,
}
options.RenewalEnabled = true

err := etcdlock.LockWithOptions(ctx, "order:123", options, func() error {
return doBusiness()
})
lock, err := etcdlock.NewLockFromClient(ctx, "inventory:sku-1", etcdlock.DefaultLockOptions)
if err != nil {
return err
}
if err := lock.Acquire(ctx); err != nil {
return err
}
defer lock.Release(ctx)

Common Misconfigurations

  • Adding a lynx.etcd-lock YAML block and expecting the repository to validate it. There is no standalone schema.
  • Loading lynx-etcd-lock before the upstream etcd plugin is available.
  • Thinking upstream registry_namespace or ttl controls lock key layout or lock expiration. Lock expiration is code-level LockOptions.Expiration.
  • Passing invalid business keys: empty strings or values longer than 255.
  • Mixing up upstream etcd client retry settings with lock acquisition retry settings.