Финальная стабильная реализация
This commit is contained in:
@@ -12,6 +12,8 @@ from typing import Any
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine
|
||||
|
||||
from app.domain import safe_hash
|
||||
|
||||
|
||||
def postgres_ssl_context() -> ssl.SSLContext:
|
||||
ca_file = os.environ.get("PG_CA_FILE")
|
||||
@@ -83,9 +85,12 @@ class Repository:
|
||||
WITH candidates AS (
|
||||
SELECT id
|
||||
FROM han_app.sync_queue
|
||||
WHERE status IN ('pending','retry_wait')
|
||||
AND next_attempt_at <= now()
|
||||
AND (locked_until IS NULL OR locked_until < now())
|
||||
WHERE (
|
||||
status IN ('pending','retry_wait') AND next_attempt_at <= now()
|
||||
)
|
||||
OR (
|
||||
status='leased' AND locked_until < now()
|
||||
)
|
||||
ORDER BY next_attempt_at, created_at
|
||||
FOR UPDATE SKIP LOCKED
|
||||
LIMIT :limit
|
||||
@@ -156,7 +161,7 @@ class Repository:
|
||||
"""
|
||||
)
|
||||
async with self.engine.begin() as connection:
|
||||
return (
|
||||
workflow_id = (
|
||||
await connection.execute(
|
||||
sql,
|
||||
{
|
||||
@@ -167,6 +172,17 @@ class Repository:
|
||||
},
|
||||
)
|
||||
).scalar_one()
|
||||
await connection.execute(
|
||||
text(
|
||||
"""
|
||||
UPDATE bitrix_sync.workflow_instances
|
||||
SET state='running',current_step='load_profile',updated_at=now()
|
||||
WHERE id=:id AND state IN ('created','running')
|
||||
"""
|
||||
),
|
||||
{"id": workflow_id},
|
||||
)
|
||||
return workflow_id
|
||||
|
||||
async def complete_task(self, task: LeasedTask, workflow_id: uuid.UUID) -> bool:
|
||||
async with self.engine.begin() as connection:
|
||||
@@ -280,8 +296,12 @@ class Repository:
|
||||
"""
|
||||
WITH candidates AS (
|
||||
SELECT id FROM bitrix_sync.webhook_inbox
|
||||
WHERE status IN ('received','retry_wait') AND next_attempt_at<=now()
|
||||
AND (locked_until IS NULL OR locked_until<now())
|
||||
WHERE (
|
||||
status IN ('received','retry_wait') AND next_attempt_at<=now()
|
||||
)
|
||||
OR (
|
||||
status='processing' AND locked_until<now()
|
||||
)
|
||||
ORDER BY next_attempt_at,received_at
|
||||
FOR UPDATE SKIP LOCKED LIMIT :limit
|
||||
)
|
||||
@@ -345,7 +365,8 @@ class Repository:
|
||||
text(
|
||||
"""
|
||||
UPDATE han_app.client_profiles
|
||||
SET full_name=:full_name,citizenship=:citizenship,email=:email,updated_at=now()
|
||||
SET full_name=:full_name,citizenship=:citizenship,email=:email,
|
||||
source_updated_at=:source_updated_at,updated_at=now()
|
||||
WHERE user_id=:user_id AND record_status='A'
|
||||
"""
|
||||
),
|
||||
@@ -354,6 +375,7 @@ class Repository:
|
||||
"full_name": full_name,
|
||||
"citizenship": citizenship,
|
||||
"email": email,
|
||||
"source_updated_at": source_updated_at,
|
||||
},
|
||||
)
|
||||
await connection.execute(
|
||||
@@ -363,14 +385,20 @@ class Repository:
|
||||
(id,mapping_id,user_id,external_id,full_name_hash,email_hash,
|
||||
citizenship_hash,source_updated_at,last_applied_source,
|
||||
last_webhook_received_at,created_at,updated_at)
|
||||
SELECT gen_random_uuid(),m.id,:user_id,:external_id,
|
||||
encode(digest(coalesce(:full_name,''),'sha256'),'hex'),
|
||||
encode(digest(coalesce(:email,''),'sha256'),'hex'),
|
||||
encode(digest(coalesce(:citizenship,''),'sha256'),'hex'),
|
||||
:source_updated_at,:source,
|
||||
CASE WHEN :source='webhook' THEN now() END,now(),now()
|
||||
SELECT gen_random_uuid(),m.id,:user_id,
|
||||
CAST(:external_id AS varchar(128)),
|
||||
CAST(:full_name_hash AS varchar(64)),
|
||||
CAST(:email_hash AS varchar(64)),
|
||||
CAST(:citizenship_hash AS varchar(64)),
|
||||
CAST(:source_updated_at AS timestamptz),
|
||||
CAST(:source AS varchar(24)),
|
||||
CASE WHEN CAST(:source AS varchar(24))='webhook'
|
||||
THEN now() END,
|
||||
now(),now()
|
||||
FROM bitrix_sync.entity_external_mapping m
|
||||
WHERE m.entity_id=:user_id AND m.external_id=:external_id AND m.status='active'
|
||||
WHERE m.entity_id=:user_id
|
||||
AND m.external_id=CAST(:external_id AS varchar(128))
|
||||
AND m.status='active'
|
||||
ON CONFLICT (mapping_id) DO UPDATE
|
||||
SET full_name_hash=excluded.full_name_hash,email_hash=excluded.email_hash,
|
||||
citizenship_hash=excluded.citizenship_hash,
|
||||
@@ -385,9 +413,9 @@ class Repository:
|
||||
{
|
||||
"user_id": user_id,
|
||||
"external_id": external_id,
|
||||
"full_name": full_name,
|
||||
"citizenship": citizenship,
|
||||
"email": email,
|
||||
"full_name_hash": safe_hash(full_name or ""),
|
||||
"citizenship_hash": safe_hash(citizenship or ""),
|
||||
"email_hash": safe_hash(email or ""),
|
||||
"source_updated_at": source_updated_at,
|
||||
"source": source,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user