From b57cb47de30239c34e73c7537c7e0f9576375aed Mon Sep 17 00:00:00 2001 From: t0xa Date: Tue, 3 Feb 2026 09:51:17 +0300 Subject: [PATCH] Update repo from work PC --- .vscode/settings.json | 2 +- drawings/dict_and_set_in_memory.puml | 0 ivideon/faq_с_Лешей.puml | 0 ivideon/puml/faces/report_creation.puml | 115 ++++-------------- .../python_generics}/main.py | 0 python/schemes/dict_in_memory_before36.puml | 28 +++++ .../dict_in_memory_post36_resize_1.puml | 34 ++++++ python/to_thread/timeline.puml | 0 python/to_thread/timeline_2.puml | 0 python/to_thread/with_to_thread.puml | 0 python/to_thread/wo_to_thread.puml | 36 ++++++ 11 files changed, 125 insertions(+), 90 deletions(-) create mode 100644 drawings/dict_and_set_in_memory.puml create mode 100644 ivideon/faq_с_Лешей.puml rename {python_generics => python/python_generics}/main.py (100%) create mode 100644 python/schemes/dict_in_memory_before36.puml create mode 100644 python/schemes/dict_in_memory_post36_resize_1.puml create mode 100644 python/to_thread/timeline.puml create mode 100644 python/to_thread/timeline_2.puml create mode 100644 python/to_thread/with_to_thread.puml create mode 100644 python/to_thread/wo_to_thread.puml diff --git a/.vscode/settings.json b/.vscode/settings.json index a27878b..64d1694 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "workbench.colorTheme": "Box UK Contrast (rainglow)", + "workbench.colorTheme": "Default Dark Modern", "cSpell.words": [ "descr", "dotenv", diff --git a/drawings/dict_and_set_in_memory.puml b/drawings/dict_and_set_in_memory.puml new file mode 100644 index 0000000..e69de29 diff --git a/ivideon/faq_с_Лешей.puml b/ivideon/faq_с_Лешей.puml new file mode 100644 index 0000000..e69de29 diff --git a/ivideon/puml/faces/report_creation.puml b/ivideon/puml/faces/report_creation.puml index e7ef9ad..b08f5c4 100644 --- a/ivideon/puml/faces/report_creation.puml +++ b/ivideon/puml/faces/report_creation.puml @@ -1,96 +1,33 @@ -@startuml - title Создание отчёта о рабочем времени (face_work_time_json) +@startgantt +printscale daily zoom 3 +[Sprint 2026-2] requires 14 days +Project starts 2026-01-26 +-- API-9487 -- +[Sprint 2026-2] starts 2026-01-26 - actor Client - participant "face/api" as API - database "MongoDB\nuser_reports" as ReportsDB - participant "report_checker\n(Worker)" as Checker - participant "reporter.py" as Reporter - participant "WorkTimeJsonReport" as WorkTime - participant "data_loader" as DataLoader - database "MongoDB\nface_events" as EventsDB - database "MongoDB\nfaces" as FacesDB - participant "tools.py" as Tools - database "Redis" as Redis +[Разбор задачи] starts 2026-01-26 +[Разбор задачи] is colored in lightgreen - == 1. Создание задачи на отчёт == - Client -> API: POST /reports\n(type=face_work_time_json) - API -> API: FaceReport.create()\nvalidate options, build query - API -> ReportsDB: insert(status='in_queue') - API --> Client: {success: true, id: report_id} +[Установка PersonSDK на ноду] requires 1 days +[Установка PersonSDK на ноду] is colored in red +[Установка PersonSDK на ноду] starts 2026-01-27 - == 2. Обработка отчёта воркером == - loop каждые SLEEP_INTERVAL секунд - Checker -> ReportsDB: find_one_and_update\n(status='in_queue' → 'in_progress') - end +[Докеризация PersonSDK] starts 2026-01-28 +[Докеризация PersonSDK] starts at [Установка PersonSDK на ноду]'s end +[Докеризация PersonSDK] is colored in lightgreen +[Докеризация PersonSDK] requires 2 days - Checker -> Checker: ProcessPoolExecutor\ncreate_report_sync(report) - note right: Новый процесс\nс asyncio.run() +[Нагрузочное тестирование PersonSDK] starts 2026-01-30 +[Нагрузочное тестирование PersonSDK] is colored in lightgreen +[Нагрузочное тестирование PersonSDK] requires 4 days - Checker -> Reporter: create_report(report) - Reporter -> Reporter: @with_context\nустановить контекст пользователя - Reporter -> Reporter: Выбрать класс из REGISTRY\n(face_work_time_json → WorkTimeJsonReport) - Reporter -> WorkTime: make_report() +[Докеризация TevianSDK] starts 2026-02-02 +[Докеризация TevianSDK] is colored in lightgreen +[Докеризация TevianSDK] requires 1 days - == 3. Загрузка данных == - WorkTime -> DataLoader: get_events(query) - DataLoader -> EventsDB: find(query)\n[best_shot_time, face_id, camera_id] - EventsDB --> DataLoader: events[] - DataLoader --> WorkTime: events - WorkTime -> DataLoader: get_faces(galleries, events,\ncameras_in, cameras_out, tz) - - loop для каждого события - DataLoader -> DataLoader: result[face_id] = GroupedFace(face_id) - DataLoader -> DataLoader: group.handle(best_shot_time, direction) - end - - DataLoader -> DataLoader: _get_faces_without_events()\n(лица из галерей без событий) - DataLoader -> FacesDB: find(_id NOT IN face_ids,\ngallery IN galleries) - FacesDB --> DataLoader: faces_without_events - - DataLoader -> DataLoader: face_ids = events + faces_without_events - - == 4. Обогащение данных фотографиями == - DataLoader -> DataLoader: _get_faces_data(face_ids) - DataLoader -> FacesDB: find(_id IN face_ids)\n[person, photos, description, gallery_id] - FacesDB --> DataLoader: faces_data[] - - loop для каждого face - DataLoader -> DataLoader: _get_photo(face_data) - alt photos пустой или None - DataLoader --> DataLoader: return None - note right #pink: **ПРИЧИНА 1**\nphotos отсутствует - else photos есть - DataLoader -> DataLoader: найти default фото\nили первое из списка - DataLoader -> Tools: get_thumb_url(photo) - alt есть thumbnails.thumbnail_200.url - Tools --> DataLoader: url - else есть thumbnails.thumbnail_200.obj_ref - Tools -> Tools: storage.generate_presigned_url() - Tools --> DataLoader: presigned_url - else нет thumbnail_200 - Tools --> DataLoader: None - note right #pink: **ПРИЧИНА 2**\nнет thumbnail_200 - end - end - DataLoader -> DataLoader: face.photo = photo_url - end - - DataLoader --> WorkTime: List[GroupedFace] - - == 5. Генерация и сохранение == - WorkTime -> WorkTime: _generate(query, faces, tz, schedule) - note right: Формирует JSON:\n[name, photo, face_id, ...] - - WorkTime -> Redis: setex(key, json, TTL=1 day) - WorkTime -> ReportsDB: update(status='done',\n_redis_key=key) - - == 6. Получение результата == - Client -> API: GET /reports/{id}/json - API -> ReportsDB: find(_id=id) - API -> Redis: get(_redis_key) - Redis --> API: json_data - API --> Client: {summary: {...}, details: {...}} - - @enduml +-- API-9488 -- +-- API-9489 -- +2026-01-31 to 2026-02-01 are colored LightBlue +2026-02-07 to 2026-02-08 are colored LightBlue +@endgantt diff --git a/python_generics/main.py b/python/python_generics/main.py similarity index 100% rename from python_generics/main.py rename to python/python_generics/main.py diff --git a/python/schemes/dict_in_memory_before36.puml b/python/schemes/dict_in_memory_before36.puml new file mode 100644 index 0000000..210dbd2 --- /dev/null +++ b/python/schemes/dict_in_memory_before36.puml @@ -0,0 +1,28 @@ +@startuml dict_before_36 +package "PyDictObject" { + card "ma_size: 8" as size + card "ma_used: 3" as used + note right of used + Реально используемых записей + end note +} + +package "Hash Table Array (размер=8)" { + card "Index 0:\n[empty]" as idx0 #FFE6E6 + card "Index 1:\nhash=0x12AF\nkey→'name'\nvalue→'John'" as idx1 #E6F3FF + card "Index 2:\n[empty]" as idx2 #FFE6E6 + card "Index 3:\nhash=0x7F23\nkey→'age'\nvalue→25" as idx3 #E6F3FF + card "Index 4:\n[empty]" as idx4 #FFE6E6 + card "Index 5:\nhash=0x3B81\nkey→'city'\nvalue→'Moscow'" as idx5 #E6F3FF + card "Index 6:\n[empty]" as idx6 #FFE6E6 + card "Index 7:\n[empty]" as idx7 #FFE6E6 +} + +note bottom of idx0 + 5 из 8 слотов пусты + Это "мертвое" пространство +end note + +size --> idx0 +used --> idx1 +@enduml diff --git a/python/schemes/dict_in_memory_post36_resize_1.puml b/python/schemes/dict_in_memory_post36_resize_1.puml new file mode 100644 index 0000000..f19d185 --- /dev/null +++ b/python/schemes/dict_in_memory_post36_resize_1.puml @@ -0,0 +1,34 @@ +@startuml compact_dict_before_resize +title Compact Dict (3.6+) ПЕРЕД resize - capacity=8 + +package "Индексный массив [8]" { + card "idx[0]: EMPTY (-1)" as i0 #FFE6E6 + card "idx[1]: 2" as i1 #E6F3FF + card "idx[2]: EMPTY (-1)" as i2 #FFE6E6 + card "idx[3]: 0" as i3 #E6F3FF + card "idx[4]: EMPTY (-1)" as i4 #FFE6E6 + card "idx[5]: 3" as i5 #E6F3FF + card "idx[6]: 1" as i6 #E6F3FF + card "idx[7]: 4" as i7 #E6F3FF +} + +package "Таблица записей (entries) [5]" { + card "entry[0]:\nhash('name')=0x1A3\nkey='name'\nvalue='Alice'" as e0 + card "entry[1]:\nhash('age')=0x2E6\nkey='age'\nvalue=25" as e1 + card "entry[2]:\nhash('city')=0x4B1\nkey='city'\nvalue='Moscow'" as e2 + card "entry[3]:\nhash('job')=0x7D5\nkey='job'\nvalue='Dev'" as e3 + card "entry[4]:\nhash('id')=0x9F7\nkey='id'\nvalue=42" as e4 +} + +i3 --> e0 +i6 --> e1 +i1 --> e2 +i5 --> e3 +i7 --> e4 + +note bottom of e4 + dk_nentries = 5 + dk_usable = 3 (осталось мест) +end note + +@enduml \ No newline at end of file diff --git a/python/to_thread/timeline.puml b/python/to_thread/timeline.puml new file mode 100644 index 0000000..e69de29 diff --git a/python/to_thread/timeline_2.puml b/python/to_thread/timeline_2.puml new file mode 100644 index 0000000..e69de29 diff --git a/python/to_thread/with_to_thread.puml b/python/to_thread/with_to_thread.puml new file mode 100644 index 0000000..e69de29 diff --git a/python/to_thread/wo_to_thread.puml b/python/to_thread/wo_to_thread.puml new file mode 100644 index 0000000..b597cce --- /dev/null +++ b/python/to_thread/wo_to_thread.puml @@ -0,0 +1,36 @@ +@startuml scenario1_blocking_io +title Синхронная I/O БЕЗ to_thread() - Event Loop заблокирован + +participant "Event Loop\n(Main Thread)" as EL +participant GIL +participant "OS Kernel" as OS + +note over EL,GIL #FFB6C1: 🔒 GIL удерживается + +EL -> EL: async def handler() +EL -> EL: data = requests.get(url) 🚨 + +note over EL #FFB6C1 + **Event Loop ЗАБЛОКИРОВАН!** + Другие async задачи ждут + Тысячи корутин простаивают +end note + +EL -> GIL: Удерживает GIL +EL -> OS: socket.recv() (системный вызов) + +note over OS + Ядро ОС читает данные + из сети + (это может занять секунды!) +end note + +OS --> EL: Данные получены + +note over EL #FFD700 + Event Loop снова свободен + Но время потеряно! +end note + +EL -> EL: return data +@enduml