ZHIWEI666 commited on
Commit
79604c9
·
verified ·
1 Parent(s): 5a5bab3

Upload 8 files

Browse files
Files changed (5) hide show
  1. app.py +4 -1
  2. owned_thread.py +25 -1
  3. resource_work.py +45 -0
  4. router_items.py +6 -5
  5. router_wallet.py +0 -0
app.py CHANGED
@@ -70,7 +70,7 @@ from router_users_social import router as users_social_router
70
  from router_items import (router as items_router, start_resource_reads, stop_resource_reads, close_resource_reads) # 📦 内容管理(工具/Skill/应用/推荐)
71
  from router_comments import (router as comments_router, start_comment_writes, stop_comment_writes, close_comment_writes) # 💬 评论系统
72
  from router_messages import (router as messages_router, start_message_io, stop_message_io, close_message_io) # ✉️ 私信系统
73
- from router_wallet import router as wallet_router # 💰 钱包/提现
74
  from router_proxy import router as proxy_router # 🔗 代理下载
75
  from router_posts import (router as posts_router, start_posts_io, stop_posts_io, close_posts_io) # 💬 讨论区
76
  from router_prompts import (router as prompts_router, start_prompts_io, stop_prompts_io, close_prompts_io) # ✨ 提示词市场
@@ -294,6 +294,7 @@ async def on_startup():
294
  start_identity_io()
295
  start_shared_work()
296
  start_open_sql()
 
297
  start_resource_work()
298
  start_resource_reads()
299
  start_comment_writes()
@@ -358,6 +359,7 @@ async def _shutdown_resources():
358
  failures.call('log_start', logger.info, "🛑 ComfyUI-Ranking API 正在关闭...")
359
  failures.call('stop_warmup', stop_startup_warmup, app.state)
360
  for stage, stop in (
 
361
  ('stop_resource_reads', stop_resource_reads), ('stop_comment_writes', stop_comment_writes),
362
  ('stop_posts', stop_posts_io), ('stop_prompts', stop_prompts_io),
363
  ('stop_messages', stop_message_io), ('stop_resources', stop_resource_work), ('stop_open_sql', stop_open_sql), ('stop_shared', stop_shared_work),
@@ -374,6 +376,7 @@ async def _shutdown_resources():
374
  failures.call('stop_' + name, request_periodic_stop, app.state, (name,))
375
  for stage, close, args in (
376
  ('wait_warmup', wait_startup_warmup, (app.state,)),
 
377
  ('close_resource_reads', close_resource_reads, ()), ('close_comment_writes', close_comment_writes, ()),
378
  ('close_posts', close_posts_io, ()), ('close_prompts', close_prompts_io, ()),
379
  ('close_messages', close_message_io, ()), ('close_resources', close_resource_work, ()), ('close_open_sql', close_open_sql, ()), ('close_shared', close_shared_work, ()),
 
70
  from router_items import (router as items_router, start_resource_reads, stop_resource_reads, close_resource_reads) # 📦 内容管理(工具/Skill/应用/推荐)
71
  from router_comments import (router as comments_router, start_comment_writes, stop_comment_writes, close_comment_writes) # 💬 评论系统
72
  from router_messages import (router as messages_router, start_message_io, stop_message_io, close_message_io) # ✉️ 私信系统
73
+ from router_wallet import (router as wallet_router, start_wallet_sql, stop_wallet_sql, close_wallet_sql) # 💰 钱包/提现
74
  from router_proxy import router as proxy_router # 🔗 代理下载
75
  from router_posts import (router as posts_router, start_posts_io, stop_posts_io, close_posts_io) # 💬 讨论区
76
  from router_prompts import (router as prompts_router, start_prompts_io, stop_prompts_io, close_prompts_io) # ✨ 提示词市场
 
294
  start_identity_io()
295
  start_shared_work()
296
  start_open_sql()
297
+ start_wallet_sql()
298
  start_resource_work()
299
  start_resource_reads()
300
  start_comment_writes()
 
359
  failures.call('log_start', logger.info, "🛑 ComfyUI-Ranking API 正在关闭...")
360
  failures.call('stop_warmup', stop_startup_warmup, app.state)
361
  for stage, stop in (
362
+ ('stop_wallet_sql', stop_wallet_sql),
363
  ('stop_resource_reads', stop_resource_reads), ('stop_comment_writes', stop_comment_writes),
364
  ('stop_posts', stop_posts_io), ('stop_prompts', stop_prompts_io),
365
  ('stop_messages', stop_message_io), ('stop_resources', stop_resource_work), ('stop_open_sql', stop_open_sql), ('stop_shared', stop_shared_work),
 
376
  failures.call('stop_' + name, request_periodic_stop, app.state, (name,))
377
  for stage, close, args in (
378
  ('wait_warmup', wait_startup_warmup, (app.state,)),
379
+ ('close_wallet_sql', close_wallet_sql, ()),
380
  ('close_resource_reads', close_resource_reads, ()), ('close_comment_writes', close_comment_writes, ()),
381
  ('close_posts', close_posts_io, ()), ('close_prompts', close_prompts_io, ()),
382
  ('close_messages', close_message_io, ()), ('close_resources', close_resource_work, ()), ('close_open_sql', close_open_sql, ()), ('close_shared', close_shared_work, ()),
owned_thread.py CHANGED
@@ -1,7 +1,7 @@
1
  """等待所属同步工作真实终态;内部取消也不能遗留仍读写资源的线程。"""
2
  import asyncio
3
  from functools import wraps
4
- from inspect import iscoroutinefunction, isasyncgenfunction, isgeneratorfunction
5
  import threading
6
 
7
 
@@ -142,3 +142,27 @@ def owned_sync_endpoint(group):
142
  return await group.run(endpoint, *args, **kwargs)
143
  return invoke
144
  return decorate
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """等待所属同步工作真实终态;内部取消也不能遗留仍读写资源的线程。"""
2
  import asyncio
3
  from functools import wraps
4
+ from inspect import Parameter, signature, iscoroutinefunction, isasyncgenfunction, isgeneratorfunction
5
  import threading
6
 
7
 
 
142
  return await group.run(endpoint, *args, **kwargs)
143
  return invoke
144
  return decorate
145
+
146
+
147
+ def owned_session_endpoint(group, session_factory, session_parameter):
148
+ def decorate(endpoint):
149
+ if iscoroutinefunction(endpoint) or isasyncgenfunction(endpoint) or isgeneratorfunction(endpoint):
150
+ raise TypeError('owned session endpoint must be a synchronous function')
151
+ original = signature(endpoint)
152
+ if session_parameter not in original.parameters:
153
+ raise ValueError('missing owned session parameter')
154
+ if any(parameter.kind not in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY)
155
+ for parameter in original.parameters.values()):
156
+ raise TypeError('owned session endpoint requires named parameters')
157
+ public = original.replace(parameters=[parameter for name, parameter in original.parameters.items()
158
+ if name != session_parameter])
159
+ @wraps(endpoint)
160
+ async def invoke(*args, **kwargs):
161
+ arguments = public.bind(*args, **kwargs).arguments
162
+ def execute():
163
+ with session_factory() as session:
164
+ return endpoint(**arguments, **{session_parameter: session})
165
+ return await group.run(execute)
166
+ invoke.__signature__ = public
167
+ return invoke
168
+ return decorate
resource_work.py CHANGED
@@ -1,6 +1,7 @@
1
  """资源写入与可选预缓存的准入和关闭归属。"""
2
  import asyncio
3
  import logging
 
4
 
5
  from fastapi import HTTPException
6
  from owned_thread import OwnedThreadGroup, owned_sync_endpoint
@@ -34,6 +35,49 @@ class ResourceWork:
34
  async def run(self, function, *args, **kwargs):
35
  return await self.writes.run(function, *args, **kwargs)
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  def background(self, factory):
38
  if not self._accepting or len(self._tasks) >= self.background_capacity:
39
  return False
@@ -83,6 +127,7 @@ class ResourceWork:
83
  _resource_work = ResourceWork()
84
  run_resource_write = _resource_work.run
85
  resource_write_endpoint = owned_sync_endpoint(_resource_work)
 
86
  start_resource_background = _resource_work.background
87
  start_resource_work = _resource_work.start
88
  stop_resource_work = _resource_work.stop
 
1
  """资源写入与可选预缓存的准入和关闭归属。"""
2
  import asyncio
3
  import logging
4
+ from functools import wraps
5
 
6
  from fastapi import HTTPException
7
  from owned_thread import OwnedThreadGroup, owned_sync_endpoint
 
35
  async def run(self, function, *args, **kwargs):
36
  return await self.writes.run(function, *args, **kwargs)
37
 
38
+ def endpoint(self, function):
39
+ @wraps(function)
40
+ async def invoke(*args, **kwargs):
41
+ return await self.operation(function, *args, **kwargs)
42
+ return invoke
43
+
44
+ async def operation(self, function, *args, **kwargs):
45
+ if not self._accepting or len(self._tasks) >= self.background_capacity:
46
+ raise HTTPException(status_code=503, detail='资源处理繁忙,请稍后重试')
47
+
48
+ async def execute():
49
+ try:
50
+ return True, await function(*args, **kwargs)
51
+ except BaseException as error:
52
+ return False, error
53
+
54
+ coroutine = execute()
55
+ try:
56
+ task = asyncio.create_task(coroutine)
57
+ except BaseException:
58
+ coroutine.close()
59
+ raise
60
+ self._tasks.add(task)
61
+ cancelled = None
62
+ try:
63
+ while not task.done():
64
+ try:
65
+ await asyncio.shield(task)
66
+ except asyncio.CancelledError as error:
67
+ if cancelled is None:
68
+ cancelled = error
69
+ task.cancel()
70
+ if task.cancelled():
71
+ raise cancelled or asyncio.CancelledError()
72
+ succeeded, result = task.result()
73
+ if cancelled is not None:
74
+ raise cancelled
75
+ if not succeeded:
76
+ raise result
77
+ return result
78
+ finally:
79
+ self._tasks.discard(task)
80
+
81
  def background(self, factory):
82
  if not self._accepting or len(self._tasks) >= self.background_capacity:
83
  return False
 
127
  _resource_work = ResourceWork()
128
  run_resource_write = _resource_work.run
129
  resource_write_endpoint = owned_sync_endpoint(_resource_work)
130
+ resource_operation_endpoint = _resource_work.endpoint
131
  start_resource_background = _resource_work.background
132
  start_resource_work = _resource_work.start
133
  stop_resource_work = _resource_work.stop
router_items.py CHANGED
@@ -1,5 +1,5 @@
1
- from resource_work import run_resource_write, start_resource_background, resource_write_endpoint
2
- from owned_thread import OwnedThreadGroup, owned_sync_endpoint
3
  # router_items.py
4
  from fastapi import APIRouter, HTTPException, Depends, Request
5
  from rate_limit import shared_limit
@@ -11,7 +11,6 @@ import re
11
  import urllib.request
12
  import urllib.error
13
  import json
14
- import asyncio
15
  import 数据库连接 as db
16
  from models import ItemCreate, ItemUpdate, RatingRequest
17
  from 安全认证 import require_auth, check_ownership, is_admin
@@ -496,13 +495,14 @@ async def update_item(request: Request, item_id: str, update_data: ItemUpdate, c
496
  # ==========================================
497
  @router.post("/api/check_updates")
498
  @shared_limit(30)
 
499
  async def check_github_updates(request: Request, current_user: str = Depends(require_auth)):
500
  """
501
  遍历所有 GitHub 类型的工具,获取最新 commit hash,存入 versions.json
502
  """
503
  if not is_admin(current_user):
504
  raise HTTPException(status_code=403, detail="无权限")
505
- items_db = await asyncio.to_thread(db.load_data, "items.json", default_data=[], strict=True, skip_cache=True)
506
  updated_count = 0
507
  for item in items_db:
508
  if not item.get('link', '').startswith('https://github.com/'):
@@ -788,9 +788,10 @@ def toggle_item_favorite(request: Request, item_id: str, current_user: str = Dep
788
  # ==========================================
789
  @router.post("/api/items/{item_id}/refresh_cache")
790
  @shared_limit(3)
 
791
  async def refresh_item_cache(request: Request, item_id: str, current_user: str = Depends(require_auth)):
792
  """手动触发指定资源的 ZIP 预缓存刷新,仅限作者调用"""
793
- items_db = db.load_data("items.json", default_data=[])
794
 
795
  # 查找目标 item
796
  target_item = None
 
1
+ from resource_work import run_resource_write, start_resource_background, resource_write_endpoint, resource_operation_endpoint
2
+ from owned_thread import OwnedThreadGroup, owned_sync_endpoint, run_owned_thread
3
  # router_items.py
4
  from fastapi import APIRouter, HTTPException, Depends, Request
5
  from rate_limit import shared_limit
 
11
  import urllib.request
12
  import urllib.error
13
  import json
 
14
  import 数据库连接 as db
15
  from models import ItemCreate, ItemUpdate, RatingRequest
16
  from 安全认证 import require_auth, check_ownership, is_admin
 
495
  # ==========================================
496
  @router.post("/api/check_updates")
497
  @shared_limit(30)
498
+ @resource_operation_endpoint
499
  async def check_github_updates(request: Request, current_user: str = Depends(require_auth)):
500
  """
501
  遍历所有 GitHub 类型的工具,获取最新 commit hash,存入 versions.json
502
  """
503
  if not is_admin(current_user):
504
  raise HTTPException(status_code=403, detail="无权限")
505
+ items_db = await run_owned_thread(db.load_data, "items.json", default_data=[], strict=True, skip_cache=True)
506
  updated_count = 0
507
  for item in items_db:
508
  if not item.get('link', '').startswith('https://github.com/'):
 
788
  # ==========================================
789
  @router.post("/api/items/{item_id}/refresh_cache")
790
  @shared_limit(3)
791
+ @resource_operation_endpoint
792
  async def refresh_item_cache(request: Request, item_id: str, current_user: str = Depends(require_auth)):
793
  """手动触发指定资源的 ZIP 预缓存刷新,仅限作者调用"""
794
+ items_db = await run_owned_thread(db.load_data, "items.json", default_data=[])
795
 
796
  # 查找目标 item
797
  target_item = None
router_wallet.py CHANGED
The diff for this file is too large to render. See raw diff