[~] Refactor
This commit is contained in:
parent
70cf5e6bad
commit
c350db8ee4
@ -1,5 +1,5 @@
|
|||||||
from .config import tiktok_config
|
from .config import tiktok_config
|
||||||
from .utils import kombu_register_json_dataclass
|
from .utils import kombu_register_json_dataclass, Backend
|
||||||
|
|
||||||
import celery
|
import celery
|
||||||
import redis
|
import redis
|
||||||
@ -9,13 +9,17 @@ c = tiktok_config()
|
|||||||
app = celery.Celery(
|
app = celery.Celery(
|
||||||
__name__,
|
__name__,
|
||||||
broker=c.celery_broker,
|
broker=c.celery_broker,
|
||||||
result_backend=c.celery_result_backend,
|
#result_backend=c.celery_result_backend,
|
||||||
|
#backend=Backend,
|
||||||
|
#result_backend=c.celery_result_backend,
|
||||||
accept_content=['json-dataclass'],
|
accept_content=['json-dataclass'],
|
||||||
task_serializer='json-dataclass',
|
task_serializer='json-dataclass',
|
||||||
result_serializer='json-dataclass',
|
result_serializer='json-dataclass',
|
||||||
|
task_track_started=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
kombu_register_json_dataclass()
|
kombu_register_json_dataclass()
|
||||||
|
app._backend = Backend(app=app, url=c.celery_result_backend)
|
||||||
|
|
||||||
|
|
||||||
app.autodiscover_tasks(c.celery_imports)
|
app.autodiscover_tasks(c.celery_imports)
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import celery.app.task
|
import celery.app.task
|
||||||
|
import celery.backends.redis
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
import inspect
|
import inspect
|
||||||
@ -36,7 +38,11 @@ def shared_task(func: Optional[Callable[Any, Any]]=None, **kwargs: Any) -> Any:
|
|||||||
# return decorator
|
# return decorator
|
||||||
#else:
|
#else:
|
||||||
# return decorator2
|
# return decorator2
|
||||||
return celery.shared_task(base=Task, **kwargs)
|
return celery.shared_task(
|
||||||
|
base=Task,
|
||||||
|
track_started=True,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
def is_async() -> bool:
|
def is_async() -> bool:
|
||||||
try:
|
try:
|
||||||
@ -45,6 +51,61 @@ def is_async() -> bool:
|
|||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
class Backend(celery.backends.redis.RedisBackend):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
return super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _store_result(self, task_id, result, state,
|
||||||
|
traceback=None, request=None, **kwargs):
|
||||||
|
meta = self._get_result_meta(result=result, state=state,
|
||||||
|
traceback=traceback, request=request, task_id=task_id,)
|
||||||
|
meta['task_id'] = celery.backends.base.bytes_to_str(task_id)
|
||||||
|
|
||||||
|
# Retrieve metadata from the backend, if the status
|
||||||
|
# is a success then we ignore any following update to the state.
|
||||||
|
# This solves a task deduplication issue because of network
|
||||||
|
# partitioning or lost workers. This issue involved a race condition
|
||||||
|
# making a lost task overwrite the last successful result in the
|
||||||
|
# result backend.
|
||||||
|
current_meta = self._get_task_meta_for(task_id)
|
||||||
|
|
||||||
|
if current_meta['status'] == celery.states.SUCCESS:
|
||||||
|
return result
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._set_with_state(self.get_key_for_task(task_id), self.encode(meta), state)
|
||||||
|
except celery.backends.base.BackendStoreError as ex:
|
||||||
|
raise celery.backends.base.BackendStoreError(str(ex), state=state, task_id=task_id) from ex
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _get_result_meta(
|
||||||
|
self,
|
||||||
|
*args,
|
||||||
|
task_id: Optional[str]=None,
|
||||||
|
state: Optional[str]=None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
current_meta = None
|
||||||
|
|
||||||
|
if not task_id is None:
|
||||||
|
current_meta = self._get_task_meta_for(task_id)
|
||||||
|
|
||||||
|
res = super()._get_result_meta(*args, state=state, **kwargs)
|
||||||
|
|
||||||
|
if state == celery.states.STARTED:
|
||||||
|
if not 'date_started' in res:
|
||||||
|
res['date_started'] = datetime.datetime.now()
|
||||||
|
|
||||||
|
for k in ['date_started',]:
|
||||||
|
if k in current_meta:
|
||||||
|
res[k] = current_meta[k]
|
||||||
|
|
||||||
|
print([args, state, kwargs, res])
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
class Task(celery.app.task.Task):
|
class Task(celery.app.task.Task):
|
||||||
def __call__(self, *args, **kwargs) -> Any:
|
def __call__(self, *args, **kwargs) -> Any:
|
||||||
res = super().__call__(*args, **kwargs)
|
res = super().__call__(*args, **kwargs)
|
||||||
@ -56,6 +117,35 @@ class Task(celery.app.task.Task):
|
|||||||
#def apply(self, *args, **kwargs):
|
#def apply(self, *args, **kwargs):
|
||||||
# return self.__call__(*args, **kwargs)
|
# return self.__call__(*args, **kwargs)
|
||||||
|
|
||||||
|
#def before_start(self, task_id: str, *args, **kwargs):
|
||||||
|
# self.update_state(None, celery.states.STARTED)
|
||||||
|
#
|
||||||
|
# meta = self.backend._get_task_meta_for(task_id)
|
||||||
|
#
|
||||||
|
# assert isinstance(meta, dict)
|
||||||
|
#
|
||||||
|
# if not 'date_started' in meta:
|
||||||
|
# meta['date_started']
|
||||||
|
#
|
||||||
|
# self._set_with_state(self.get_key_for_task(task_id), self.encode(meta), state)
|
||||||
|
|
||||||
|
#def update_state(
|
||||||
|
# self,
|
||||||
|
# *args,
|
||||||
|
# state: Optional[str]=None,
|
||||||
|
# meta: Optional[dict[str,Any]]=None,
|
||||||
|
# **kwargs
|
||||||
|
#):
|
||||||
|
# print(['blah', meta, state])
|
||||||
|
#
|
||||||
|
# if not meta is None:
|
||||||
|
# logger.info(json.dumps(dict(state=state)))
|
||||||
|
#
|
||||||
|
# if not 'date_started' in meta and state == celery.states.STARTED:
|
||||||
|
# meta['date_started'] = datetime.datetime.now()
|
||||||
|
#
|
||||||
|
# return super().update_stae(*args, state=state, meta=meta, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _loads(
|
def _loads(
|
||||||
cls,
|
cls,
|
||||||
|
Loading…
Reference in New Issue
Block a user