TaskManager 이해 가이드
직접 기능 호출에서 관리 가능한 실행 Framework로
이 문서는 TaskManager를 처음 접하는 독자가 왜 필요한지, 무엇이 달라졌는지, 실제로 어떻게 동작하는지를 순서대로 이해하도록 구성한 대표 입문서다. 설명은 현재 기준 소스인 a1-packages-mr6/apps/DeviceAgent에 맞췄다.
TaskManager는 새 이동·청정 기능이 아니라, 이미 존재하는 기기 기능을 task와 workflow로 접수해 순서·대기·취소·실패·실제 완료를 공통 관리하는 DeviceAgent 내부 실행 제어 계층이다.
이 문서를 읽는 순서
| 순서 | 읽을 부분 | 확인할 내용 |
|---|---|---|
| 1 | 개요·1~3장·개발·AAR 관점 | TaskManager의 구성, 책임, 개발 방식과 외부 Framework 사용 형태 |
| 2 | 4장 | 단일 실행, 복합 workflow, 취소, 지연 실행 사례 |
| 3 | 5~9장 | 내부 계층, queue, workflow와 완료 evidence 흐름 |
| 4 | 10~12장 | TaskManager의 책임 경계와 AOSP·소스 위치 |
| 5 | 13~15장 | 구현 증거, 실기기 검증 수준과 후속 문서 |
처음 읽을 때는 1~5장으로 전체 구조를 잡고, 구현이나 검증이 필요할 때 뒤쪽 세부 장으로 내려가면 된다.
TaskManager 개요
TaskManager는 DeviceAgent가 가진 이동, 청정, 설정, TTS, Security, Schedule 같은 기능을 새로 구현하는 모듈이 아니다. 여러 호출자가 요청한 기기 행동을 공통 작업 형식으로 접수하고, 실행 전 검사부터 순서·대기·취소·완료·실패 기록까지 관리하는 runtime이다.
어떤 문제를 해결하는가
| 기존 문제 | TaskManager가 제공하는 해결 방식 |
|---|---|
| 호출 성공과 실제 기기 동작 완료를 구분하기 어려움 | domain callback과 상태를 완료 evidence로 사용 |
| PUI, IoT, App, 음성마다 실행·오류 처리가 달라짐 | source를 보존한 공통 task envelope과 lifecycle 제공 |
| 이동 후 청정처럼 여러 동작의 순서를 호출자가 직접 연결 | parent workflow와 step dependency로 순서 관리 |
| 동시에 들어온 이동·청정·TTS 요청이 충돌할 수 있음 | domain queue, priority와 resource policy로 조정 |
| 취소 시 현재 기능만 멈추고 다음 단계가 남을 수 있음 | parent, active child와 pending step을 함께 정리 |
| timeout과 실패 이유가 로그 문자열로 흩어짐 | reason_code, recoverability와 suggested action으로 구조화 |
| N분 뒤 한 번 실행할 작업이 caller timer에 의존 | durable scheduled record와 due admission으로 관리 |
| UI와 QA가 현재 진행 단계를 별도로 추정 | task/workflow/step event와 correlation ID 제공 |
| source별 연결 코드가 늘며 변경 영향이 확산 | task 계약, policy, executor와 evidence 경계로 변경을 국소화 |
TaskManager가 관리하는 실행 단위
| 실행 단위 | 의미 | 예시 |
|---|---|---|
| Task | 하나의 실행 요청과 lifecycle | 스테이션 복귀, 음량 변경, TTS 재생 |
| Workflow | 여러 task의 실행 관계를 가진 parent | 안방 이동 → 청정 → 스테이션 복귀 |
| Step | workflow 내부의 실행·대기·결과 단위 | setMoveTo, startBasicAirClear |
| Parallel child | 서로 다른 queue에서 함께 실행할 수 있는 child | 청정과 안내 TTS의 동시 진행 |
| Scheduled record | 미래 시각에 admission할 task 또는 workflow | 30분 뒤 이동 후 청정 |
| TaskRecord | 상태·시간·진행률·결과·실패 사유의 기준 record | taskId, state, current step, reason |
Core 구성요소
| 구성요소 | 담당 역할 |
|---|---|
| Ingress / Public API | submitTask, submitWorkflow, schedule, query, cancel 접수 |
| Admission / Validation | alias, schema, caller, 현재 상태, 자원과 안전조건 확인 |
| Policy Registry | method별 mode, queue, priority, timeout, retry와 cancel 정책 결정 |
| Queue Runtime | 같은 domain 작업의 순서와 우선순위 관리 |
| Workflow Engine | 순차·조건·병렬·지연 step과 parent/child 결과 관리 |
| Deferred Scheduler | 미래 실행 record 저장, due·missed-run 판정과 일반 runtime 재진입 |
| Executor Registry | taskMethod를 기존 DeviceAgent domain 기능에 연결 |
| Completion Gate | callback·상태 evidence가 충족될 때 실제 완료 판정 |
| Event / Reason | 진행·완료·실패·취소와 복구 가능성을 외부에 전달 |
| Monitor / Metrics | task, queue, step, latency와 terminal 결과 관찰 |
외부 시스템이 넣는 것과 돌려받는 것
| 방향 | 주요 정보 | 용도 |
|---|---|---|
| 요청 입력 | taskMethod, params, source, request/trace ID |
실행할 기능과 호출 출처 식별 |
| 실행 정책 | priority, queue, timeout, completion target | 실행 순서와 종료 조건 결정 |
| workflow 입력 | subTasks, dependency, condition, parallel group | 복합 동작 관계 표현 |
| 예약 입력 | trigger type, triggerAtMs, relative delay |
미래의 일회성 실행 의도 저장 |
| 즉시 반환 | accepted, task/workflow/schedule ID | 요청 접수와 추후 조회 기준 제공 |
| 진행 event | state, progress, current step | UI·monitor·호출자 상태 갱신 |
| terminal event | completed, failed, cancelled, result | 실제 작업 종료 판정 |
| 실패 정보 | reason, params, recoverability, suggested action | 재시도·사용자 확인·상위 재판단 결정 |
대표적으로 관리할 수 있는 작업
| 유형 | 대표 요청 | TaskManager가 관리하는 부분 |
|---|---|---|
| 단일 실행 | “스테이션으로 복귀해” | movement queue, 도킹 evidence, timeout과 실패 |
| 순차 workflow | “안방 가서 청정하고 복귀해” | 이동 완료 후 청정, 청정 종료 후 복귀 |
| 병렬 workflow | 청정 중 상태 안내 TTS | 서로 다른 queue 실행과 parent 결과 집계 |
| 취소·선점 | 이동 중 PUI 취소 또는 긴급 정지 | active child 정지, pending step 제거, cancel event |
| 단기 예약 | “30분 뒤 안방 가서 청정해” | 예약 저장, due admission, 실행 시점 상태 재확인 |
| 상태 조회 | 현재 task와 queue 상태 확인 | running/pending task와 current step 반환 |
| 장기 interaction | Welcome, Security, 앱 기반 측정 | 사용자 완료·취소 또는 domain lifecycle event 대기 |
| 실패 복구 | 저전력, 경로 막힘, 알 수 없는 공간 | 구조화 reason과 복구 성격을 상위 계층에 제공 |
TaskManager의 핵심 산출물은 기능 실행 자체가 아니라 실행 상태를 신뢰할 수 있게 만드는 공통 기록과 event다. 어떤 요청이 언제 접수됐고, 어느 queue에서 어떤 step을 실행했으며, 무엇을 근거로 완료 또는 실패했는지를 한 흐름으로 남긴다.
1. 먼저 구분해야 하는 세 영역
| 영역 | 담당 질문 | 대표 구성 | TaskManager와의 관계 |
|---|---|---|---|
| 기존 기기 기능 | 실제로 어떻게 이동하고 청정하는가 | MovingController, CleaningTransaction, ScheduleManager, WssManager, LlmManager |
TaskManager가 재구현하지 않고 호출한다. |
| 실행 관리 | 언제 실행하고, 무엇을 기다리며, 실패·취소를 어떻게 닫는가 | TaskManager, policy, queue, workflow, executor, completion evidence |
이 문서의 핵심 범위다. |
| 상위 판단 | 사용자가 무엇을 원하는가, 어떤 행동을 조합할 것인가 | PUI, IoT, App, 예약, On-device/Cloud planner | 정해진 task 또는 workflow를 TaskManager에 전달한다. |
TaskManager는 자연어를 해석하는 planner도 아니고 모터를 직접 구동하는 HAL도 아니다. 결정된 기기 행동을 신뢰성 있게 수행하고 결과 증거를 남기는 실행 control plane이다.
2. 5분 요약: 무엇이 바뀌었는가
AS-IS: 기능 API는 있었지만 실행 lifecycle은 호출자가 관리
기존 DeviceAgent는 이미 다양한 기능을 제공했다.
PUI / IoT / System App / 내부 모듈
-> IDeviceControl.sendModuleCommand(Bundle)
-> DeviceAgent
-> MainApi.executeMethod(...)
-> 기능별 manager / controller
-> AMR · MCU · Schedule · WSS · LLM
단일 버튼 동작에는 충분했지만 여러 단계가 이어지면 호출자가 다음 책임까지 떠안았다.
- 명령 접수와 실제 물리 동작 완료의 구분
- 이동 완료 후 청정을 시작하는 순서 제어
- 중간 취소 시 현재 동작과 다음 대기 동작 정리
- timeout, 저전력, 경로 막힘 등 실패 해석
- PUI, IoT, App 등 source별 callback과 상태 표시
TO-BE: 기존 기능 앞뒤에 공통 실행 계약을 추가
PUI / IoT / System App / 예약 / 상위 Planner
-> submitTask / submitWorkflow
-> admission · policy · queue · workflow
-> executor adapter
-> 기존 DeviceAgent 기능
-> domain callback / state evidence
-> COMPLETED / FAILED / CANCELLED + reason
| 비교 축 | AS-IS | TO-BE |
|---|---|---|
| 호출 단위 | 기능 method 직접 호출 | submitTask, submitWorkflow |
| 실행 식별 | source별 request 또는 로그 | taskId, requestId, traceId, parent/step ID |
| 순서 | 호출자 코드가 연결 | workflow의 subTasks와 선행 조건으로 표현 |
| 대기 | caller가 callback을 해석 | completionTarget evidence까지 대기 |
| 취소 | 기능별 stop을 직접 호출 | parent task, active child, pending step을 함께 정리 |
| 실패 | 로그 문자열 또는 기능별 callback | reason_code, 복구 가능성, 권장 조치 |
| 상태 표시 | source마다 다르게 구현 | 공통 lifecycle과 event timeline |
| 단기 지연 | caller timer에 의존 | durable scheduled record 또는 step trigger |
| 개발 단위 | caller별 method·callback 연결 코드 | 재사용 가능한 task capability 계약 |
| 회귀 검증 | source별 시나리오를 개별 검증 | validation·policy·lifecycle·evidence 계약 검증 |
개발 관점: 애드훅 연결에서 Task 단위 개발로
AS-IS에서 커지기 쉬운 애드훅 구조
호출자가 기능 API, callback, timeout, 취소와 후속 동작을 모두 연결하면 같은 정책이 여러 서비스에 반복된다. 기능 하나의 변경이 호출자별 분기와 예외 처리까지 퍼지고, 조합 기능은 별도 callback 체인으로 늘어난다.
TO-BE의 표준 기능 온보딩 절차
새 기능은 다음 여섯 지점만 명시적으로 연결한다.
| 구성요소 | 한 줄 설명 |
|---|---|
TaskBundleValidator |
필수 입력과 type을 검사한다. |
TaskPolicyRegistry |
queue, mode, priority, timeout과 조건을 선언한다. |
TaskExecutorBootstrap |
canonical method를 기존 기능 API에 연결한다. |
TaskCompletionWatcher |
실제 완료 evidence를 기다린다. |
TaskReasonContract |
실패를 공통 reason으로 변환한다. |
| cancel·compensation adapter | 사용자 중단과 안전 복구를 연결한다. |
기능 코드는 유지하고 실행 관리만 공통화
Executor는 기존 이동·청정·화면 API를 다시 구현하지 않고 위임한다. 따라서 기능 알고리즘은 도메인에 남고, 수명주기와 실행 정책만 공통 Framework가 소유한다.
복합 기능은 callback 체인이 아니라 workflow 데이터로 표현
setMoveTo
-> startBasicAirClear
-> returnToStation
각 단계는 depends_on, completion target과 failure policy를 가진다. 이미 검증된 Task
조각을 다시 조합하므로 새 시나리오를 만들 때 기능 코드를 복제하지 않는다.
개발 변경 범위가 국소화되는 방식
- 기능 입력 변경은 validator와 adapter에서 처리한다.
- 실행 정책 변경은 policy catalog에서 검토한다.
- 물리 완료 변경은 completion bridge에서 처리한다.
- 조합 순서 변경은 Workflow 데이터에서 처리한다.
- 사용자 표현과 제품 목표는 호출자 또는 상위 기획 계층에 남긴다.
코드 리뷰에서 확인할 공통 기준
method, 입력, 실행 허용, queue, timeout, 완료, 취소, reason과 실기기 evidence가 한 기능 카드에서 추적돼야 한다. 상세 클래스와 구현 절차는 Source-Level Implementation Guide를 기준으로 한다.
Framework 사용 형태: TaskManagerClient AAR
두 계층을 분리하는 이유
DeviceAgent 내부 Core는 실행 lifecycle을 소유한다. product-level AAR은 시스템 앱이 문자열과 Bundle을 직접 조립하지 않도록 typed request와 callback을 제공한다.
앱 개발자에게 노출되는 API
TaskSubmitRequest.builder()TaskWorkflowRequest.builder()TaskManagerClient.submitTask()와submitWorkflow()- 상태 조회와 취소 API
TaskManagerClientCallback.onTaskEvent()
System App 사용 예
TaskWorkflowRequest request = TaskWorkflowRequest.builder("room_clean_return")
.addTask(moveTask)
.addTask(cleanTask)
.addTask(returnTask)
.build();
client.submitWorkflow(request, callback);
Framework API로서 지켜야 할 계약
AAR과 Core는 method, 필드 기본값, alias, event와 reason 의미가 같아야 한다. AAR은 Core runtime을 포함하거나 Binder 권한을 우회하지 않는다.
소스와 배포 산출물
배포 산출물은 taskmanagerclient-release.aar이며, 공개 API와 builder의 전체 사양은
TaskManagerClient AAR API Specification에만 유지한다.
3. 왜 method return만으로는 부족한가
기기 제어에서는 요청 전달 성공과 사용자가 기대한 결과 달성이 다르다. returnToStation 호출이 예외 없이 반환돼도 경로가 막히거나, 도킹하지 못하거나, 사용자가 이동을 취소할 수 있다.
command accepted != movement completed
returnToStation command 실행
-> movement 상태 관찰
-> station charging/docking evidence
-> Task COMPLETED
그래서 TaskManager의 완료는 단순 return 값이 아니라 domain이 제공하는 증거로 닫힌다. 이것이 도입 전과 후를 가르는 핵심이다.
4. 예시로 보는 구축 전과 구축 후
예시 A. “스테이션으로 복귀해”
AS-IS
PUI 또는 App
-> returnToStation 직접 호출
-> 호출 성공 반환
-> 실제 도킹 실패는 이동 로그나 별도 상태에서 확인
TO-BE
submitTask(taskMethod=returnToStation)
-> movement queue
-> 기존 returnToStation 실행
-> movement.stationCharging evidence 대기
-> COMPLETED 또는 FAILED(reason_code)
| 관점 | 이전 | 이후 |
|---|---|---|
| 사용자 | 명령 접수와 완료가 혼동될 수 있음 | 이동 중·도킹 완료·실패를 구분해 안내 가능 |
| UI | 자체 상태 추정 | task status/event를 표시 |
| QA | 로그와 화면을 수동 대조 | taskId와 완료 evidence로 판정 |
예시 B. “안방으로 가서 청정하고 복귀해”
AS-IS
setMoveTo 호출
-> 도착 callback을 caller가 해석
-> setAirCleanerOperation 호출
-> 청정 완료 또는 정지 조건 관리
-> returnToStation 호출
caller process가 종료되거나 중간 단계가 실패하면 어디까지 실행됐고 무엇을 취소해야 하는지 caller별 보상 로직이 필요하다.
TO-BE
submitWorkflow
1. setMoveTo
완료 증거: movement.arrived
2. setAirCleanerOperation
선행 조건: step 1 completed
완료 증거: cleaning.stopped
3. returnToStation
선행 조건: step 2 completed
완료 증거: movement.stationCharging
첫 번째 command가 반환됐다는 이유만으로 청정을 시작하지 않는다. movement.arrived가 관측돼 첫 단계가 완료된 뒤 두 번째 단계로 진행한다.
예시 C. 이동 중 PUI에서 취소
| AS-IS | TO-BE |
|---|---|
| PUI가 별도 stop method 호출 | cancelTask(parentTaskId) 요청 |
| 원래 요청과 stop 관계가 약함 | parent, active child, cancel command가 같은 lifecycle에 연결 |
| 다음 단계 제거는 caller 책임 | pending step과 parallel child를 TaskManager가 정리 |
| 실제 정지 여부는 별도 확인 | stop 실행과 terminal event를 함께 추적 |
취소는 record만 CANCELLED로 바꾸는 것이 아니다. policy에 등록된 cancel 또는 compensation method를 domain에 전달하고 실행 중 child와 대기 step을 정리한다.
예시 D. “30초 후 나이트모드로 바꿔”
| AS-IS | TO-BE |
|---|---|
| caller process 안의 timer | scheduleTask durable record |
| process 종료 시 유실 가능 | due record를 복원해 일반 admission 경로로 진입 |
| 예약과 실행 ID가 분리 | scheduleId -> taskId -> terminal event 연결 |
| 중복 실행 방지는 caller 책임 | due admission과 idempotency 경계에서 관리 |
제품의 반복 Schedule과 TaskManager deferred task는 목적이 다르다. 반복 생활 일정은 기존 Schedule domain이 소유하고, “N분 뒤 한 번 실행” 같은 단기 지연 작업은 TaskManager scheduling이 관리한다.
예시 E. “30분 뒤 안방으로 가서 청정해줘”
이 요청은 단일 설정 변경이 아니라 실행 시각과 두 단계 행동을 함께 가진 일회성 workflow 예약이다.
scheduleWorkflow
trigger: relativeDelayMs=1800000
subTasks:
1. setMoveTo(안방) -> movement.arrived
2. startBasicAirClear -> cleaning terminal evidence
등록 시점에는 이동이나 청정을 시작하지 않는다. SCHEDULED record와 절대
triggerAtMs를 저장하고, 30분 뒤 runDueScheduledTasks가 현재 위치·배터리·busy
상태와 공간 정보를 다시 확인한다. 실행 가능하면 기존 submitWorkflow로 재진입하고,
불가능하면 동작하지 않은 채 구조화된 reason을 남긴다.
| 구분 | 현재 확인 수준 |
|---|---|
| MR6 소스 | scheduleWorkflow, durable store, due admission과 기존 workflow 재진입 구현 |
| 자동 테스트 | 예약 계약, 저장·복원, due와 missed-run 경계 검증 |
| 실기기 | 단일 예약 등록·복원·조회·취소와 수동 due 실행 확인 |
| 남은 gate | 예약된 이동+청정 workflow의 exact/periodic 자동 due 전체 E2E |
따라서 “이 구조로 소화할 수 있다”와 “모든 실기기 자동 실행이 release 검증까지 끝났다”는 구분해야 한다. 반복되는 매일·매주 청정은 기존 제품 Schedule에 등록하고, 이 예시처럼 한 번만 지연 실행하는 workflow는 TaskManager scheduling이 담당한다.
5. Framework 전체 구조
그림의 왼쪽에서 오른쪽으로는 요청 접수와 실행 경로, 오른쪽에서 아래를 거쳐 TaskManager로 돌아오는 흐름은 실제 완료 evidence와 결과 보고 경로다. 기존 DeviceAgent domain은 기능을 계속 소유하고, TaskManager는 그 앞뒤에서 실행 lifecycle을 관리한다.
| 계층 | 주요 구성 | 책임 |
|---|---|---|
| Ingress Adapter | PUI, IoT, App, schedule, bridge | source와 correlation을 보존해 공통 task envelope 생성 |
| Public Facade | MainApi, handleControlMethod() |
task control API와 legacy API의 공존 지점 |
| Admission | alias resolver, validator, caller/state/resource policy | 실행 전 payload·권한·상태·자원 확인 |
| Runtime Core | TaskManager, record, queue, workflow, scheduler |
lifecycle, 순서, priority, timeout, 취소, 지연 |
| Policy Catalog | TaskPolicyRegistry |
method별 mode, queue, priority, retry, cancel 정의 |
| Executor Registry | TaskExecutorRegistry, bootstrap |
canonical taskMethod를 domain adapter에 연결 |
| Domain Adapter | movement, cleaning, schedule, security, TTS 등 | payload를 정규화하고 기존 기능 호출 |
| Existing Domain | manager, controller, command bridge | 실제 제품 기능과 하드웨어 상태 소유 |
| Evidence Layer | completion store/watcher, callback bridge | 실제 완료·중단 사실을 task lifecycle로 변환 |
| Observe/Result | event, reason, reporter, monitor | 상태·실패·상관관계를 외부에 제공 |
6. 단일 task가 처리되는 순서
현재 submitTask의 핵심 흐름은 다음과 같다.
1. TaskManager 활성 여부 확인
2. alias를 canonical taskMethod로 정규화
3. method별 payload schema 검증
4. source/caller policy 확인
5. 기기 상태와 domain 자원 충돌 확인
6. CPU·RAM·thermal admission 확인
7. preempt policy 적용
8. mode·queue·priority·timeout 결정
9. registry에서 executor 생성
10. TaskRecord 생성
11. DIRECT / QUEUED_WAIT / ASYNC 실행
12. 필요한 completion evidence 대기
13. terminal event와 reason 발행
대표 요청은 다음 의미를 갖는다.
method=submitTask
taskMethod=returnToStation
source=PUI
requestId=pui-return-001
traceId=pui-return-001
priority=HIGH
completionTarget=movement.stationCharging
timeoutMs=240000
Cloud, IoT, PUI, System App은 같은 의미의 field와 lifecycle을 사용하고 source와 correlation만 보존한다.
7. Queue, mode, priority가 해결하는 문제
실행 mode
| mode | 의미 | 대표 예 |
|---|---|---|
DIRECT |
짧은 조회를 즉시 실행하고 반환 | 배터리, 펌웨어, 현재 상태 |
QUEUED_WAIT |
queue에서 실행하고 caller가 terminal까지 대기 | 설정 변경, 정지, schedule CRUD |
ASYNC |
taskId를 먼저 반환하고 event로 추적 | 이동, 복귀, 청정, TTS, Security |
queue
동일 queue는 single worker와 priority queue로 순서를 관리한다. 서로 다른 queue는 policy가 허용할 때 병렬로 실행할 수 있다.
movement queue: setMoveTo -> returnToStation
cleaning queue: start -> stop
ai queue: TTS -> stopTTS
같은 queue: 높은 priority 우선, 같은 priority는 FIFO
다른 queue: 자원 충돌 policy를 통과하면 병렬 가능
공개 domain queue는 movement, cleaning, state, update, sound, settings, ai, routine, schedule, interaction, security, mapping, emergency, default로 구성된다. workflow parent는 내부 workflow queue를 사용한다.
| 개념 | 역할 |
|---|---|
| priority | EMERGENCY, HIGH, CONTROL, NORMAL, BACKGROUND 순으로 대기 순서 결정 |
| append | 현재 queue 뒤에 추가 |
| clear pending | 실행 전 대기 task 제거 |
| cancel running | 현재 실행 task까지 취소 시도 |
| replace queue/all | 해당 queue 또는 전체 대기 흐름 교체 |
priority는 source 이름만으로 결정하면 안 된다. 동일한 음성 입력도 단순 청정과 긴급 정지는 다른 실행 정책을 가져야 한다.
8. Workflow가 관리하는 것
workflow는 자연어 문장이 아니라 구조화된 subTasks의 실행 관계다.
| 기능 | 관리 내용 |
|---|---|
| 순차 실행 | 배열 순서와 선행 step 완료 |
| 조건 | step_completed, step_output_equals |
| 조건 불충족 | skip 또는 parent fail |
| 상대 지연 | after_step + delayMs |
| 병렬 실행 | parallelGroup과 join policy |
| 부분 실패 | fail parent, continue, partial success |
| parent 취소 | active child 취소와 pending step 중단 |
중요한 현재 경계
- parent workflow는 내부 workflow queue의 single worker에서 관리된다.
- 순차 step은 parent workflow worker 안에서 실행된다.
- parallel child는 각 domain queue에 독립 task로 등록된다.
- 모든 workflow step이 항상 domain queue를 통해 완전 직렬화된다고 과장하면 안 된다.
- 짧은
after_step지연은 workflow worker가 대기할 수 있지만 긴 지연은 durable scheduler로 넘기는 것이 맞다.
9. 완료 evidence와 실패 reason
기존 domain callback
-> TaskCompletionStateStore.mark(target, key, status)
-> TaskCompletionWatcher.waitFor(...)
-> executor 완료
-> TaskRecord COMPLETED
-> onTaskEvent(COMPLETED)
| 동작 | 대표 완료 근거 |
|---|---|
| 공간 이동 | movement.arrived |
| 스테이션 복귀 | 도킹/충전 상태 |
| 청정 | started/stopped 또는 step/report 완료 |
| TTS | playback ended |
| 화면 전환 | target screen applied |
| Welcome/interaction | interaction lifecycle completed |
| Security | mode lifecycle event |
| 앱 기반 측정 | app session ended 또는 사용자 완료/취소 event |
오래된 callback이 새 task를 완료시키지 않도록 task 시작 시각 이후의 evidence만 인정하고, 필요하면 area ID 또는 completion key로 범위를 좁힌다.
실패는 사용자 문장 한 줄이 아니라 상위 시스템이 판단 가능한 구조로 남긴다.
reason_code
reason_params
recoverability
suggested_action
requires_cloud_decision
예를 들어 LOW_BATTERY는 기기가 도킹 후 재개할 수 있는 실패일 수 있고, UNKNOWN_ROOM은 사용자에게 공간명을 다시 확인해야 하는 실패다. TaskManager는 사실과 복구 성격을 제공하고 PUI·IoT·상위 planner가 자기 UX 정책에 맞게 안내한다.
10. TaskManager가 하는 일과 하지 않는 일
| TaskManager가 하는 일 | TaskManager가 하지 않는 일 |
|---|---|
| task/workflow 접수와 validation | 자연어 intent 분류 |
| queue, priority, timeout, retry | 사용자 대화 생성 |
| step dependency와 parallel join | 이동 경로 계산 알고리즘 재구현 |
| cancel/preempt/compensation | 청정·Security business logic 재구현 |
| callback 기반 실제 완료 판정 | Android public SDK API 제공 |
| event, reason, correlation 제공 | 모든 실패에서 자동 재계획 결정 |
재계획이 필요한 실패에서는 requires_cloud_decision 같은 신호를 제공할 수 있지만 목표 변경과 사용자 재질문은 상위 판단 계층의 책임이다.
11. AOSP 안에서의 위치
DeviceAgent는 android.uid.system을 사용하는 privileged product app이며 TaskManager는 그 내부 package다.
Application / System App ingress
-> Binder/AIDL product IPC
-> DeviceAgent privileged app
-> MainApi
-> TaskManager
-> existing domain managers
-> vendor service / HAL / MCU / AMR
TaskManager는 frameworks/base의 Android framework service가 아니며 Android public SDK도 아니다. 다만 A1 제품 관점에서는 여러 system app과 domain 기능을 공통 계약으로 연결하는 Product Execution Framework 역할을 한다.
12. 현재 소스에서 확인할 위치
기준 checkout:
/home/silogood/work/1.A1_SoC_new/SoC/a1-packages-mr6
| 확인 목적 | 소스 |
|---|---|
| MainApi 삽입점 | apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/main/api/MainApi.java |
| control API와 runtime core | .../task/TaskManager.java |
| mode·queue·priority·cancel policy | .../task/TaskPolicyRegistry.java |
| executor 등록 | .../task/TaskExecutorRegistry.java, TaskExecutorBootstrap.java |
| payload 검증 | .../task/TaskBundleValidator.java |
| 완료 저장·대기 | .../task/TaskCompletionStateStore.java, TaskCompletionWatcher.java |
| 구조화 실패 | .../task/TaskReasonContract.java |
| planning snapshot | .../task/DevicePlanningContextProvider.java |
| monitor/event relay | .../task/TaskMonitorReporter.java, TaskEventListener.java |
| deferred admission | .../task/TaskScheduledAdmissionRunner.java, TaskScheduledAdmissionReceiver.java |
13. 구현 완료와 제품 검증을 구분하는 법
| 증거 수준 | 무엇을 말할 수 있는가 | 말할 수 없는 것 |
|---|---|---|
| Source verified | API, policy, executor, state machine이 코드에 존재 | 실기기에서 모든 domain이 정상 종료됨 |
| Automated test passed | 특정 입력·상태·실패 경계가 회귀 테스트를 통과 | 센서·AMR·PUI callback이 실제 제품에서 항상 정상 |
| Real-device evidence | 특정 빌드·기기·시나리오가 실제 callback으로 완료 | 모든 기기·환경에 대한 일반적 release 승인 |
“APK 빌드 성공”은 TaskManager 제품 검증 완료가 아니다. 실기기 acceptance에는 서명 일치, system app 배치, task event, domain callback, 실제 물리 완료, cancel/timeout 증거가 함께 필요하다.
14. TaskManager 도입이 가져오는 결과
| 이해관계자 | 얻는 변화 |
|---|---|
| 사용자 | 접수·진행·완료·실패가 더 정확하게 구분된다. |
| 기획 | 기능 버튼이 아니라 작업 단위, 완료 조건, 취소 정책을 사양화할 수 있다. |
| DeviceAgent 개발 | domain 기능은 유지하고 task 계약·policy·executor·evidence 경계에서 변경을 국소화한다. |
| App/PUI 개발 | 기능마다 callback을 다시 해석하지 않고 공통 task 상태를 사용한다. |
| Cloud/IoT | request와 terminal 결과를 correlation ID로 연결한다. |
| QA | ACK가 아니라 실제 evidence와 reason으로 판정한다. |
| 운영 | 어느 queue와 step에서 왜 멈췄는지 추적한다. |
| SoC 업체 | 기능별 개별 연동이 아니라 공통 실행 Framework 계약으로 구현 범위를 나눈다. |
가장 큰 변화는 기능 수가 늘어난 것이 아니다. 기기 행동이 추적·취소·복구 가능한 관리 대상이 됐다는 것이다.
15. 다음에 읽을 문서
| 궁금한 내용 | 다음 문서 |
|---|---|
| 전체 기술 상세와 현재 MR6 수치 | DeviceAgent TaskManager 구조와 구현 |
| task/non-task, queue, priority 정책 | DeviceAgent TaskManager 기준 사양서 |
| 실제 runtime lifecycle | DeviceAgent TaskManager 기준 사양서 |
| 코드 layer와 파일 | SoC TaskManager Source Level Implementation Guide |
| 외부 System App API | TaskManagerClient AAR API Specification |
| scheduling 현재 검증 상태 | Task Scheduling Runtime Readiness |
| 실시간 상태와 QA 운영 | TaskManager Live Monitor |
| 전체 문서 지도 | SoC TaskManager Framework |