fix(server): hata yönetimini ve dayanıklılığı iyileştir

Loop scheduler ve timer worker için hata yakalama ekle. qBit client'ta
geçici ağ hatalarını tanıyarak login durumunu sıfırla. Scheduler
hatalarında durum güncellemesi gönder ve timer worker crash önle.
This commit is contained in:
2026-01-31 11:25:51 +03:00
parent 9b495b7bf7
commit 967eb2d2a4
5 changed files with 6097 additions and 356 deletions

View File

@@ -13,6 +13,7 @@
"@fortawesome/react-fontawesome": "^0.2.2", "@fortawesome/react-fontawesome": "^0.2.2",
"@radix-ui/react-alert-dialog": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-select": "^2.1.2", "@radix-ui/react-select": "^2.1.2",
"@radix-ui/react-scroll-area": "^1.2.2",
"axios": "^1.7.7", "axios": "^1.7.7",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"react": "^18.3.1", "react": "^18.3.1",

View File

@@ -0,0 +1,27 @@
import * as React from "react";
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
import clsx from "clsx";
export const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<ScrollAreaPrimitive.Root
ref={ref}
className={clsx("relative overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full overflow-y-auto rounded-[inherit]">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollAreaPrimitive.Scrollbar
orientation="vertical"
className="flex w-2.5 touch-none select-none rounded-full bg-transparent p-0.5 opacity-100"
>
<ScrollAreaPrimitive.Thumb className="relative flex-1 rounded-full bg-slate-200" />
</ScrollAreaPrimitive.Scrollbar>
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
));
ScrollArea.displayName = "ScrollArea";

View File

@@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useState } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/Card"; import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/Card";
import { Button } from "../components/ui/Button"; import { Button } from "../components/ui/Button";
import { Input } from "../components/ui/Input"; import { Input } from "../components/ui/Input";
import { ScrollArea } from "../components/ui/ScrollArea";
import { api } from "../api/client"; import { api } from "../api/client";
import { useAppStore } from "../store/useAppStore"; import { useAppStore } from "../store/useAppStore";
import { useUiStore } from "../store/useUiStore"; import { useUiStore } from "../store/useUiStore";
@@ -360,13 +361,21 @@ export const TimerPage = () => {
<SelectItem <SelectItem
key={option.value} key={option.value}
value={option.value} value={option.value}
onClick={() => { onPointerDown={() => {
if (option.value === sortKey) { if (option.value === sortKey) {
setSortDirection((current) => setSortDirection((current) =>
current === "asc" ? "desc" : "asc" current === "asc" ? "desc" : "asc"
); );
} }
}} }}
onKeyDown={(event) => {
if (option.value !== sortKey) return;
if (event.key === "Enter" || event.key === " ") {
setSortDirection((current) =>
current === "asc" ? "desc" : "asc"
);
}
}}
> >
{option.label} {option.label}
</SelectItem> </SelectItem>
@@ -435,11 +444,13 @@ export const TimerPage = () => {
Silinen Torrent Logları Silinen Torrent Logları
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent className="space-y-3"> <CardContent className="space-y-3 overflow-hidden">
{timerLogs.length === 0 ? ( {timerLogs.length === 0 ? (
<div className="text-sm text-slate-500">Henüz log yok.</div> <div className="text-sm text-slate-500">Henüz log yok.</div>
) : ( ) : (
<div className="space-y-3"> <div className="overflow-hidden" style={{ height: 560 }}>
<ScrollArea className="h-full w-full" type="always">
<div className="space-y-3 pr-3">
{timerLogs.map((log) => ( {timerLogs.map((log) => (
<div <div
key={log.id} key={log.id}
@@ -469,6 +480,8 @@ export const TimerPage = () => {
</div> </div>
))} ))}
</div> </div>
</ScrollArea>
</div>
)} )}
</CardContent> </CardContent>
</Card> </Card>

748
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

5610
pnpm-lock_.yaml Normal file

File diff suppressed because it is too large Load Diff