refac
This commit is contained in:
@@ -82,13 +82,22 @@ class RedisDict:
|
|||||||
return [(k, json.loads(v)) for k, v in self.redis.hgetall(self.name).items()]
|
return [(k, json.loads(v)) for k, v in self.redis.hgetall(self.name).items()]
|
||||||
|
|
||||||
def set(self, mapping: dict):
|
def set(self, mapping: dict):
|
||||||
pipe = self.redis.pipeline()
|
if not mapping:
|
||||||
|
self.redis.delete(self.name)
|
||||||
|
return
|
||||||
|
|
||||||
pipe.delete(self.name)
|
# Fetch existing keys before writing so we know which ones to remove.
|
||||||
if mapping:
|
# HKEYS is cheap — it transfers only short key strings, not large JSON values.
|
||||||
pipe.hset(self.name, mapping={k: json.dumps(v) for k, v in mapping.items()})
|
existing_keys = set(self.redis.hkeys(self.name))
|
||||||
|
new_keys = set(mapping.keys())
|
||||||
|
keys_to_remove = existing_keys - new_keys
|
||||||
|
|
||||||
pipe.execute()
|
# HSET first (add/update all new values), then HDEL (remove stale keys).
|
||||||
|
# We never DELETE the whole hash — this eliminates the race window
|
||||||
|
# where concurrent readers would see an empty models dict.
|
||||||
|
self.redis.hset(self.name, mapping={k: json.dumps(v) for k, v in mapping.items()})
|
||||||
|
if keys_to_remove:
|
||||||
|
self.redis.hdel(self.name, *keys_to_remove)
|
||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -237,49 +237,49 @@
|
|||||||
|
|
||||||
{#if role === 'admin'}
|
{#if role === 'admin'}
|
||||||
<a
|
<a
|
||||||
href="/playground"
|
href="/playground"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
class="flex rounded-xl py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition cursor-pointer select-none"
|
class="flex rounded-xl py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition cursor-pointer select-none"
|
||||||
on:click={async (e) => {
|
on:click={async (e) => {
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
show = false;
|
show = false;
|
||||||
goto('/playground');
|
goto('/playground');
|
||||||
if ($mobile) {
|
if ($mobile) {
|
||||||
await tick();
|
await tick();
|
||||||
showSidebar.set(false);
|
showSidebar.set(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class=" self-center mr-3">
|
<div class=" self-center mr-3">
|
||||||
<Code className="size-5" strokeWidth="1.5" />
|
<Code className="size-5" strokeWidth="1.5" />
|
||||||
</div>
|
</div>
|
||||||
<div class=" self-center truncate">{$i18n.t('Playground')}</div>
|
<div class=" self-center truncate">{$i18n.t('Playground')}</div>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="/admin"
|
href="/admin"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
class="flex rounded-xl py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition cursor-pointer select-none"
|
class="flex rounded-xl py-1.5 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition cursor-pointer select-none"
|
||||||
on:click={async (e) => {
|
on:click={async (e) => {
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
show = false;
|
show = false;
|
||||||
goto('/admin');
|
goto('/admin');
|
||||||
if ($mobile) {
|
if ($mobile) {
|
||||||
await tick();
|
await tick();
|
||||||
showSidebar.set(false);
|
showSidebar.set(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class=" self-center mr-3">
|
<div class=" self-center mr-3">
|
||||||
<UserGroup className="w-5 h-5" strokeWidth="1.5" />
|
<UserGroup className="w-5 h-5" strokeWidth="1.5" />
|
||||||
</div>
|
</div>
|
||||||
<div class=" self-center truncate">{$i18n.t('Admin Panel')}</div>
|
<div class=" self-center truncate">{$i18n.t('Admin Panel')}</div>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if help}
|
{#if help}
|
||||||
|
|||||||
Reference in New Issue
Block a user