fix: change cache service to component
This commit is contained in:
parent
6fd78e7830
commit
f5c7ceb850
81
src/pages/setup/cache/cache.component.html
vendored
Normal file
81
src/pages/setup/cache/cache.component.html
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<h1>Настройка кэша</h1>
|
||||||
|
<hr/>
|
||||||
|
<p class="mat-body-2 secondary">
|
||||||
|
На этой странице вы можете выбрать и настроить параметры кэширования для приложения.
|
||||||
|
</p>
|
||||||
|
<p class="mat-body-2 secondary">
|
||||||
|
Укажите тип кэша, например, Redis, и настройте параметры подключения, чтобы улучшить производительность и снизить
|
||||||
|
нагрузку на базу данных.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form [formGroup]="databaseForm">
|
||||||
|
<p>
|
||||||
|
Выберите базу данных для хранения кэша:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<mat-form-field color="accent">
|
||||||
|
<mat-label>База данных</mat-label>
|
||||||
|
<mat-select (valueChange)="onDatabaseChange($event)">
|
||||||
|
<mat-option value="redis">Redis</mat-option>
|
||||||
|
<mat-option value="memcached">Memcached</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div style="display:flex; flex-direction: column;">
|
||||||
|
@if (database && database !== "memcached") {
|
||||||
|
<hr/>
|
||||||
|
<mat-form-field color="accent">
|
||||||
|
<mat-label>Сервер</mat-label>
|
||||||
|
<input matInput
|
||||||
|
matTooltip='Укажите сервер в формате: "winsomnia.net" или ip адреса формата IPv4 или IPv6'
|
||||||
|
required
|
||||||
|
formControlName="server">
|
||||||
|
|
||||||
|
@if (databaseForm.get('server')?.hasError('required')) {
|
||||||
|
<mat-error>
|
||||||
|
Сервер является <i>обязательным</i>
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (databaseForm.get('server')?.hasError('pattern')) {
|
||||||
|
<mat-error>
|
||||||
|
Сервер должен содержать доменное имя сервера или ip адрес IPv4 или IPv6
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field color="accent">
|
||||||
|
<mat-label>Порт</mat-label>
|
||||||
|
<input matInput
|
||||||
|
matTooltip="Укажите порт сервера"
|
||||||
|
required
|
||||||
|
formControlName="port">
|
||||||
|
|
||||||
|
@if (databaseForm.get('port')?.hasError('required')) {
|
||||||
|
<mat-error>
|
||||||
|
Порт является <i>обязательным</i>
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (databaseForm.get('port')?.hasError('pattern')) {
|
||||||
|
<mat-error>
|
||||||
|
Порт должен содержать цифры НЕ начиная с цифры 0 и далее не менее 2 цифр
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field color="accent">
|
||||||
|
<mat-label>Пароль</mat-label>
|
||||||
|
<input matInput
|
||||||
|
matTooltip="Укажите пароль"
|
||||||
|
formControlName="password"
|
||||||
|
[type]="hidePass ? 'password' : 'text'">
|
||||||
|
|
||||||
|
<button mat-icon-button matSuffix (click)="togglePassword($event)" [attr.aria-label]="'Hide password'"
|
||||||
|
[attr.aria-pressed]="hidePass">
|
||||||
|
<mat-icon>{{ hidePass ? 'visibility_off' : 'visibility' }}</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-form-field>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -1,65 +0,0 @@
|
|||||||
import {Injectable} from '@angular/core';
|
|
||||||
|
|
||||||
interface CacheEntry<T> {
|
|
||||||
data: T;
|
|
||||||
expiry: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class CacheService {
|
|
||||||
private handleQuotaExceeded(): void {
|
|
||||||
const keys: string[] = [];
|
|
||||||
const expiries: number[] = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < localStorage.length; i++) {
|
|
||||||
const key = localStorage.key(i);
|
|
||||||
if (!key) continue;
|
|
||||||
|
|
||||||
const cacheEntry = JSON.parse(localStorage.getItem(key) as string) as CacheEntry<any>;
|
|
||||||
keys.push(key);
|
|
||||||
expiries.push(cacheEntry.expiry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Удаляем самый старый элемент
|
|
||||||
const oldestIndex = expiries.indexOf(Math.min(...expiries));
|
|
||||||
localStorage.removeItem(keys[oldestIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private isQuotaExceededError(e: unknown): e is DOMException {
|
|
||||||
return e instanceof DOMException && (
|
|
||||||
e.name === 'QuotaExceededError' ||
|
|
||||||
e.name === 'NS_ERROR_DOM_QUOTA_REACHED'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
set<T>(key: string, data: T, ttl: number): void {
|
|
||||||
const expiry = Date.now() + ttl;
|
|
||||||
const cacheEntry: CacheEntry<T> = {data, expiry};
|
|
||||||
|
|
||||||
try {
|
|
||||||
localStorage.setItem(key, JSON.stringify(cacheEntry));
|
|
||||||
} catch (e) {
|
|
||||||
if (this.isQuotaExceededError(e)) {
|
|
||||||
this.handleQuotaExceeded();
|
|
||||||
localStorage.setItem(key, JSON.stringify(cacheEntry));
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get<T>(key: string): T | null {
|
|
||||||
const cached = localStorage.getItem(key);
|
|
||||||
if (!cached) return null;
|
|
||||||
|
|
||||||
const cacheEntry = JSON.parse(cached) as CacheEntry<T>;
|
|
||||||
if (Date.now() > cacheEntry.expiry) {
|
|
||||||
localStorage.removeItem(key);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cacheEntry.data;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user