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:
@@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useState } from "react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/Card";
|
||||
import { Button } from "../components/ui/Button";
|
||||
import { Input } from "../components/ui/Input";
|
||||
import { ScrollArea } from "../components/ui/ScrollArea";
|
||||
import { api } from "../api/client";
|
||||
import { useAppStore } from "../store/useAppStore";
|
||||
import { useUiStore } from "../store/useUiStore";
|
||||
@@ -360,13 +361,21 @@ export const TimerPage = () => {
|
||||
<SelectItem
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
onClick={() => {
|
||||
onPointerDown={() => {
|
||||
if (option.value === sortKey) {
|
||||
setSortDirection((current) =>
|
||||
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}
|
||||
</SelectItem>
|
||||
@@ -435,39 +444,43 @@ export const TimerPage = () => {
|
||||
Silinen Torrent Logları
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<CardContent className="space-y-3 overflow-hidden">
|
||||
{timerLogs.length === 0 ? (
|
||||
<div className="text-sm text-slate-500">Henüz log yok.</div>
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{timerLogs.map((log) => (
|
||||
<div
|
||||
key={log.id}
|
||||
className="rounded-lg border border-slate-200 bg-white px-3 py-2"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<div className="text-sm font-semibold text-slate-900">
|
||||
{log.name}
|
||||
<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) => (
|
||||
<div
|
||||
key={log.id}
|
||||
className="rounded-lg border border-slate-200 bg-white px-3 py-2"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<div className="text-sm font-semibold text-slate-900">
|
||||
{log.name}
|
||||
</div>
|
||||
<div className="text-xs text-slate-500">
|
||||
{formatBytes(log.sizeBytes)} •{" "}
|
||||
{trackerLabel(log.tracker)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-slate-400">
|
||||
{new Date(log.deletedAt).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-slate-500">
|
||||
{formatBytes(log.sizeBytes)} •{" "}
|
||||
{trackerLabel(log.tracker)}
|
||||
<div className="mt-2 flex flex-wrap gap-2 text-xs text-slate-600">
|
||||
<span>Seed: {formatDuration(log.seedingTimeSeconds)}</span>
|
||||
<span>Upload: {formatBytes(log.uploadedBytes)}</span>
|
||||
{log.tags?.length ? (
|
||||
<span>Tags: {log.tags.join(", ")}</span>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-slate-400">
|
||||
{new Date(log.deletedAt).toLocaleString()}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-2 flex flex-wrap gap-2 text-xs text-slate-600">
|
||||
<span>Seed: {formatDuration(log.seedingTimeSeconds)}</span>
|
||||
<span>Upload: {formatBytes(log.uploadedBytes)}</span>
|
||||
{log.tags?.length ? (
|
||||
<span>Tags: {log.tags.join(", ")}</span>
|
||||
) : null}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</ScrollArea>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user