Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/auth/src/EloquentUserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,8 @@ protected function registerCacheInvalidationEvents(): void
$modelClass = $this->model;

// Insert or replace the descriptor — duplicate configs collapse.
$descriptorKey = md5(
$descriptorKey = hash(
'xxh128',
($this->cacheStoreName ?? '') . '|' . $this->cachePrefix . '|' . $this->modelSegment
);

Expand Down
2 changes: 1 addition & 1 deletion src/auth/src/SessionGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public function __construct(
$this->provider = $provider;
$this->timebox = $timebox ?: new Timebox;

$classHash = sha1(static::class);
$classHash = hash('xxh128', static::class);
$this->hashedName = 'login_' . $this->name . '_' . $classHash;
$this->hashedRecallerName = 'remember_' . $this->name . '_' . $classHash;
}
Expand Down
2 changes: 1 addition & 1 deletion src/auth/src/TokenGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ protected function getContextKeyForToken(?string $token): string
return "__auth.guards.{$this->name}.user.default";
}

return "__auth.guards.{$this->name}.user." . md5($token);
return "__auth.guards.{$this->name}.user." . hash('xxh128', $token);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/boost/docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ In production, your Hypervel server should be kept running by a process monitor,
php artisan serve
```

By default, the HTTP server binds to `0.0.0.0:9501`. You may configure the server host, port, worker count, and other Swoole settings using the `HTTP_SERVER_HOST`, `HTTP_SERVER_PORT`, and `SERVER_WORKERS_NUMBER` environment variables read by `config/server.php`.
By default, the HTTP server binds to `0.0.0.0:9501` with HTTP/2 enabled. You may configure the server host, port, worker count, max requests per worker, HTTP/2 support, and other Swoole settings using the `HTTP_SERVER_HOST`, `HTTP_SERVER_PORT`, `SERVER_WORKERS`, `SERVER_MAX_REQUESTS`, and `SERVER_HTTP2` environment variables read by `config/server.php`.

<a name="directory-permissions"></a>
### Directory Permissions
Expand Down
2 changes: 1 addition & 1 deletion src/boost/docs/reverb.md
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ hypervel hard nofile 10000
<a name="workers"></a>
### Workers

Reverb runs on Swoole's native WebSocket server and shares the configured WebSocket port across your Swoole workers. Increasing the number of workers increases the amount of parallel work Reverb can perform, but each worker also uses its own memory. You may configure the worker count using the `SERVER_WORKERS_NUMBER` environment variable read by your application's `config/server.php` configuration file.
Reverb runs on Swoole's native WebSocket server and shares the configured WebSocket port across your Swoole workers. Increasing the number of workers increases the amount of parallel work Reverb can perform, but each worker also uses its own memory. You may configure the worker count using the `SERVER_WORKERS` environment variable read by your application's `config/server.php` configuration file.

In single-instance mode, Reverb uses a Swoole table to track channel subscription counts, presence member counts, webhook locks, and per-application connection limits across workers. The default table sizes are suitable for most applications, but you may tune them if you have a large number of channels or presence members:

Expand Down
2 changes: 1 addition & 1 deletion src/cache/src/FailoverStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ protected function attemptOnAllStores(string $method, array $arguments): mixed

$failedCaches[] = $store;

if (! in_array($store, $failingCaches)) {
if (! in_array($store, $failingCaches) && $this->events->hasListeners(CacheFailedOver::class)) {
$this->events->dispatch(new CacheFailedOver($store, $e));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cache/src/FileStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ protected function emptyPayload(): array
*/
public function path(string $key): string
{
$parts = array_slice(str_split($hash = sha1($key), 2), 0, 2);
$parts = array_slice(str_split($hash = hash('xxh128', $key), 2), 0, 2);

return $this->directory . '/' . implode('/', $parts) . '/' . $hash;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cache/src/Redis/AllTaggedCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public function putMany(array $values, DateInterval|DateTimeInterface|int|null $
$values,
$seconds,
$this->tags->tagIds(),
sha1($this->tags->getNamespace()) . ':'
hash('xxh128', $this->tags->getNamespace()) . ':'
);

if ($result) {
Expand Down
6 changes: 3 additions & 3 deletions src/cache/src/Redis/Console/Benchmark/BenchmarkContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public function getTagStoragePatterns(string $tagNamePrefix): array
* Returns patterns for BOTH tag modes to ensure complete cleanup
* regardless of current mode (important for --compare-tag-modes):
* - Untagged keys: {cachePrefix}{keyPrefix}* (same in both modes)
* - Tagged keys in all mode: {cachePrefix}{sha1}:{keyPrefix}* (namespaced)
* - Tagged keys in all mode: {cachePrefix}{xxh128}:{keyPrefix}* (namespaced)
*
* @param string $keyPrefix The prefix to match cache keys against
* @return array<string> Patterns to use with SCAN/KEYS commands
Expand All @@ -160,7 +160,7 @@ public function getCacheValuePatterns(string $keyPrefix): array
return [
// Untagged cache values (both modes) and any-mode tagged values
$prefix . $keyPrefix . '*',
// All-mode tagged values at {cachePrefix}{sha1}:{keyName}
// All-mode tagged values at {cachePrefix}{xxh128}:{keyName}
$prefix . '*:' . $keyPrefix . '*',
];
}
Expand Down Expand Up @@ -268,7 +268,7 @@ public function cleanup(): void
$store->tags($tags)->flush();

// 2. Clean up non-tagged benchmark keys using mode-aware patterns
// In all mode, tagged keys are at {prefix}{sha1}:{key}, so we need multiple patterns
// In all mode, tagged keys are at {prefix}{xxh128}:{key}, so we need multiple patterns
foreach ($this->getCacheValuePatterns(self::KEY_PREFIX) as $pattern) {
$this->flushKeysByPattern($storeInstance, $pattern);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function run(DoctorContext $context): CheckResult
);
$this->testAnyModeHashTtl($context, $result, $foreverTag, $foreverKey);
} else {
// All mode: key is namespaced with sha1 of tag IDs
// All mode: key is namespaced with xxh128 of tag IDs
$namespacedKey = $context->namespacedKey([$foreverTag], $foreverKey);
$keyTtl = $context->redis->ttl($context->cachePrefix . $namespacedKey);
$result->assert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function run(DoctorContext $context): CheckResult
);
$this->testAnyMode($context, $result, $tag, $key);
} else {
// All mode: key is namespaced with sha1 of tags
// All mode: key is namespaced with xxh128 of tags
// Direct get without tags will NOT find the item
$result->assert(
$context->cache->get($key) === null,
Expand Down
23 changes: 5 additions & 18 deletions src/cache/src/Redis/Console/Doctor/DoctorContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,32 +55,19 @@ public function tagHashKey(string $tag): string
return $this->store->getContext()->tagHashKey($tag);
}

/**
* Get the tag identifier (without cache prefix).
*
* Format: "_any:tag:{tagName}:entries" or "_all:tag:{tagName}:entries"
* Used for namespace computation in all mode.
*/
public function tagId(string $tag): string
{
return $this->store->getContext()->tagId($tag);
}

/**
* Compute the namespaced key for a tagged cache item in all mode.
*
* In all mode, cache keys are prefixed with sha1 of sorted tag IDs.
* Format: "{sha1}:{key}"
* In all mode, cache keys are prefixed with xxh128 of tag IDs in the requested order.
* Format: "{xxh128}:{key}"
*
* @param array<string> $tags The tag names
* @param string $key The cache key
* @return string The namespaced key
*/
public function namespacedKey(array $tags, string $key): string
{
$tagIds = array_map(fn (string $tag) => $this->tagId($tag), $tags);
sort($tagIds);
$namespace = sha1(implode('|', $tagIds));
$namespace = hash('xxh128', $this->cache->tags($tags)->getTags()->getNamespace());

return $namespace . ':' . $key;
}
Expand Down Expand Up @@ -156,7 +143,7 @@ public function getTagStoragePatterns(string $tagNamePrefix): array
* Returns patterns for BOTH tag modes to ensure complete cleanup
* regardless of current mode (e.g., if config changed between runs):
* - Untagged keys: {cachePrefix}{keyPrefix}* (same in both modes)
* - Tagged keys in all mode: {cachePrefix}{sha1}:{keyPrefix}* (namespaced)
* - Tagged keys in all mode: {cachePrefix}{xxh128}:{keyPrefix}* (namespaced)
*
* @param string $keyPrefix The prefix to match cache keys against
* @return array<string> Patterns to use with SCAN/KEYS commands
Expand All @@ -166,7 +153,7 @@ public function getCacheValuePatterns(string $keyPrefix): array
return [
// Untagged cache values (both modes) and any-mode tagged values
$this->cachePrefix . $keyPrefix . '*',
// All-mode tagged values at {cachePrefix}{sha1}:{keyName}
// All-mode tagged values at {cachePrefix}{xxh128}:{keyName}
$this->cachePrefix . '*:' . $keyPrefix . '*',
];
}
Expand Down
66 changes: 30 additions & 36 deletions src/cache/src/Redis/Console/DoctorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,55 +109,49 @@ public function handle(): int
$this->info('Checking System Requirements...');
$this->newLine();

if (! $this->runEnvironmentChecks($storeName, $store, $tagMode)) {
return self::FAILURE;
}
return $store->getContext()->withConnection(function (RedisConnection $redis) use ($repository, $store, $storeName, $tagMode) {
if (! $this->runEnvironmentChecks($storeName, $store, $tagMode, $redis)) {
return self::FAILURE;
}

$this->info('✓ All requirements met!');
$this->newLine(2);
$this->info('✓ All requirements met!');
$this->newLine(2);

$this->info("Testing cache store: <fg=cyan>{$storeName}</> ({$tagMode} mode)");
$this->newLine();
$this->info("Testing cache store: <fg=cyan>{$storeName}</> ({$tagMode} mode)");
$this->newLine();

// Get the Redis connection from the store's context
$context = $store->getContext();
$redis = $context->withConnection(fn (RedisConnection $connection) => $connection);
$doctorContext = new DoctorContext(
cache: $repository,
store: $store,
redis: $redis,
cachePrefix: $store->getPrefix(),
storeName: $storeName,
);

$doctorContext = new DoctorContext(
cache: $repository,
store: $store,
redis: $redis,
cachePrefix: $store->getPrefix(),
storeName: $storeName,
);

// Run functional checks with cleanup
try {
$this->cleanup($doctorContext, silent: true);
$this->runFunctionalChecks($doctorContext);
} finally {
$this->cleanup($doctorContext);
}
// Run functional checks with cleanup
try {
$this->cleanup($doctorContext, silent: true);
$this->runFunctionalChecks($doctorContext);
} finally {
$this->cleanup($doctorContext);
}

// Run cleanup verification after cleanup
$this->runCleanupVerification($doctorContext);
// Run cleanup verification after cleanup
$this->runCleanupVerification($doctorContext);

$this->displaySummary();
$this->displaySummary();

return $this->testsFailed === 0 ? self::SUCCESS : self::FAILURE;
return $this->testsFailed === 0 ? self::SUCCESS : self::FAILURE;
});
}

/**
* Get environment check classes.
*
* @return list<EnvironmentCheckInterface>
*/
protected function getEnvironmentChecks(string $storeName, RedisStore $store, string $tagMode): array
protected function getEnvironmentChecks(string $storeName, RedisStore $store, string $tagMode, RedisConnection $redis): array
{
// Get connection for version checks
$context = $store->getContext();
$redis = $context->withConnection(fn (RedisConnection $connection) => $connection);

return [
new PhpRedisCheck,
new RedisVersionCheck($redis, $tagMode),
Expand Down Expand Up @@ -197,11 +191,11 @@ protected function getFunctionalChecks(): array
/**
* Run environment checks. Returns false if any check fails.
*/
protected function runEnvironmentChecks(string $storeName, RedisStore $store, string $taggingMode): bool
protected function runEnvironmentChecks(string $storeName, RedisStore $store, string $taggingMode, RedisConnection $redis): bool
{
$allPassed = true;

foreach ($this->getEnvironmentChecks($storeName, $store, $taggingMode) as $check) {
foreach ($this->getEnvironmentChecks($storeName, $store, $taggingMode, $redis) as $check) {
$result = $check->run();

foreach ($result->assertions as $assertion) {
Expand Down
2 changes: 1 addition & 1 deletion src/cache/src/Redis/Support/StoreContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function tagMode(): TagMode
/**
* Get the tag identifier (without cache prefix).
*
* Used by All mode for namespace computation (sha1 of sorted tag IDs).
* Used by all mode for namespace computation (xxh128 of tag IDs in requested order).
* Format: "_any:tag:{tagName}:entries" or "_all:tag:{tagName}:entries"
*/
public function tagId(string $tag): string
Expand Down
2 changes: 1 addition & 1 deletion src/cache/src/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ public function getRaw(UnitEnum|string $key): mixed
* "genuinely absent = miss".
*
* Applies itemKey() to each key so tag-namespacing works correctly on
* TaggedCache / AllTaggedCache (which prepend sha1($tagNamespace) . ':').
* TaggedCache / AllTaggedCache (which prepend hash('xxh128', $tagNamespace) . ':').
* AnyTaggedCache overrides this method to throw, preserving the any-mode
* invariant that reads through tags are rejected.
*
Expand Down
2 changes: 1 addition & 1 deletion src/cache/src/TaggedCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function flush(): bool
*/
public function taggedItemKey(string $key): string
{
return sha1($this->tags->getNamespace()) . ':' . $key;
return hash('xxh128', $this->tags->getNamespace()) . ':' . $key;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/console/src/Scheduling/CallbackEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public function getSummaryForDisplay(): string
*/
public function mutexName(): string
{
return 'framework/schedule-' . sha1($this->description ?? '');
return 'framework/schedule-' . hash('xxh128', $this->description ?? '');
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/console/src/Scheduling/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ protected function ensureOutputIsBeingCaptured(): void
{
if (is_null($this->output)) {
$this->ensureOutputIsBeingCaptured = true;
$this->sendOutputTo(storage_path('logs/schedule-' . sha1($this->mutexName()) . '.log'));
$this->sendOutputTo(storage_path('logs/schedule-' . hash('xxh128', $this->mutexName()) . '.log'));
}
}

Expand Down Expand Up @@ -764,7 +764,7 @@ public function mutexName(): string
}

return 'framework' . DIRECTORY_SEPARATOR . 'schedule-'
. sha1($this->expression . static::normalizeCommand($this->command ?? ''));
. hash('xxh128', $this->expression . static::normalizeCommand($this->command ?? ''));
}

/**
Expand Down
Loading