1{
2 "project": "async-app-result-removal",
3 "description": "Remove Result from AsyncApp return types by moving app-alive checks to executor",
4 "phases": [
5 {
6 "id": 1,
7 "name": "Add Trampoline Check Infrastructure (macOS First)",
8 "status": "completed",
9 "tasks": [
10 {
11 "id": "1.1",
12 "description": "Add MainThreadWeak<T> newtype with unsafe Send+Sync impls to platform.rs",
13 "file": "crates/gpui/src/platform.rs",
14 "status": "completed"
15 },
16 {
17 "id": "1.2",
18 "description": "Update RunnableMeta to use Option<MainThreadWeak<AppCell>> for app field",
19 "file": "crates/gpui/src/platform.rs",
20 "status": "completed"
21 },
22 {
23 "id": "1.3",
24 "description": "Update trampoline in Mac dispatcher to check app via unsafe upgrade() before run()",
25 "file": "crates/gpui/src/platform/mac/dispatcher.rs",
26 "status": "completed"
27 },
28 {
29 "id": "1.4",
30 "description": "Update tick() in Test dispatcher to check app via unsafe upgrade() before run()",
31 "file": "crates/gpui/src/platform/test/dispatcher.rs",
32 "status": "completed"
33 },
34 {
35 "id": "1.5",
36 "description": "Add ForegroundExecutor::spawn_with_app that accepts Weak<AppCell>",
37 "file": "crates/gpui/src/executor.rs",
38 "status": "completed"
39 },
40 {
41 "id": "1.6",
42 "description": "Update AsyncApp::spawn to pass self.app wrapped in MainThreadWeak",
43 "file": "crates/gpui/src/app/async_context.rs",
44 "status": "completed"
45 },
46 {
47 "id": "1.7",
48 "description": "Update AsyncWindowContext::spawn to pass app wrapped in MainThreadWeak",
49 "file": "crates/gpui/src/app/async_context.rs",
50 "status": "completed"
51 },
52 {
53 "id": "1.8",
54 "description": "Write unit tests verifying task cancellation when app is dropped (moved to executor.rs to access pub(crate) items)",
55 "file": "crates/gpui/src/executor.rs",
56 "status": "completed",
57 "notes": "Tests moved from tests/task_cancellation.rs to executor.rs as #[cfg(test)] module because TestAppContext holds strong Rc<AppCell> preventing proper app-drop testing"
58 },
59 {
60 "id": "1.9",
61 "description": "Write unit test for nested tasks both cancelling cleanly",
62 "file": "crates/gpui/src/executor.rs",
63 "status": "completed"
64 },
65 {
66 "id": "1.10",
67 "description": "Create async_cancellation.rs example demonstrating behavior",
68 "file": "crates/gpui/examples/async_cancellation.rs",
69 "status": "completed"
70 }
71 ]
72 },
73 {
74 "id": 2,
75 "name": "Extend to Other Platforms",
76 "status": "not_started",
77 "tasks": [
78 {
79 "id": "2.1",
80 "description": "Update trampoline function in Linux dispatcher to check app status before run()",
81 "file": "crates/gpui/src/platform/linux/dispatcher.rs",
82 "status": "not_started"
83 },
84 {
85 "id": "2.2",
86 "description": "Update trampoline function in Windows dispatcher to check app status before run()",
87 "file": "crates/gpui/src/platform/windows/dispatcher.rs",
88 "status": "not_started"
89 }
90 ]
91 },
92 {
93 "id": 3,
94 "name": "Update AsyncApp API & Remove AppContext::Result",
95 "status": "not_started",
96 "tasks": [
97 {
98 "id": "3.1",
99 "description": "Rename update() -> Result<R> to try_update() -> Option<R>",
100 "file": "crates/gpui/src/app/async_context.rs",
101 "status": "not_started"
102 },
103 {
104 "id": "3.2",
105 "description": "Add new update() -> R that panics if app is gone",
106 "file": "crates/gpui/src/app/async_context.rs",
107 "status": "not_started"
108 },
109 {
110 "id": "3.3",
111 "description": "Apply try_/non-try pattern to read_entity and update_entity",
112 "file": "crates/gpui/src/app/async_context.rs",
113 "status": "not_started"
114 },
115 {
116 "id": "3.4",
117 "description": "Apply try_/non-try pattern to read_global and update_global",
118 "file": "crates/gpui/src/app/async_context.rs",
119 "status": "not_started"
120 },
121 {
122 "id": "3.5",
123 "description": "Apply try_/non-try pattern to read_window and update_window",
124 "file": "crates/gpui/src/app/async_context.rs",
125 "status": "not_started"
126 },
127 {
128 "id": "3.6",
129 "description": "Apply try_/non-try pattern to new, reserve_entity, insert_entity",
130 "file": "crates/gpui/src/app/async_context.rs",
131 "status": "not_started"
132 },
133 {
134 "id": "3.7",
135 "description": "Apply try_/non-try pattern to refresh, open_window, subscribe, has_global",
136 "file": "crates/gpui/src/app/async_context.rs",
137 "status": "not_started"
138 },
139 {
140 "id": "3.8",
141 "description": "Apply same changes to AsyncWindowContext",
142 "file": "crates/gpui/src/app/async_context.rs",
143 "status": "not_started"
144 },
145 {
146 "id": "3.9",
147 "description": "Remove type Result<T> associated type from AppContext trait",
148 "file": "crates/gpui/src/gpui.rs",
149 "status": "not_started"
150 },
151 {
152 "id": "3.10",
153 "description": "Update all AppContext trait method signatures to return R directly",
154 "file": "crates/gpui/src/gpui.rs",
155 "status": "not_started"
156 },
157 {
158 "id": "3.11",
159 "description": "Remove Flatten trait from gpui.rs",
160 "file": "crates/gpui/src/gpui.rs",
161 "status": "not_started"
162 },
163 {
164 "id": "3.12",
165 "description": "Update WeakEntity::update to remove Flatten bounds",
166 "file": "crates/gpui/src/app/entity_map.rs",
167 "status": "not_started"
168 },
169 {
170 "id": "3.13",
171 "description": "Update WeakEntity::read_with to remove Flatten bounds",
172 "file": "crates/gpui/src/app/entity_map.rs",
173 "status": "not_started"
174 },
175 {
176 "id": "3.14",
177 "description": "Update WeakEntity::update_in to remove Flatten bounds",
178 "file": "crates/gpui/src/app/entity_map.rs",
179 "status": "not_started"
180 },
181 {
182 "id": "3.15",
183 "description": "Update ExampleContext in eval crate to match new AppContext signature",
184 "file": "crates/eval/src/example.rs",
185 "status": "not_started"
186 },
187 {
188 "id": "3.16",
189 "description": "Update AsyncApp documentation",
190 "file": "crates/gpui/src/app/async_context.rs",
191 "status": "not_started"
192 },
193 {
194 "id": "3.17",
195 "description": "Run cargo test -p gpui",
196 "file": null,
197 "status": "not_started"
198 },
199 {
200 "id": "3.18",
201 "description": "Run ./script/clippy",
202 "file": null,
203 "status": "not_started"
204 },
205 {
206 "id": "3.19",
207 "description": "Verify async_cancellation example runs without panics",
208 "file": "crates/gpui/examples/async_cancellation.rs",
209 "status": "not_started"
210 },
211 {
212 "id": "3.20",
213 "description": "Manual test: close windows with pending tasks, verify no panics",
214 "file": null,
215 "status": "not_started"
216 }
217 ]
218 }
219 ],
220 "future_work": {
221 "brief": "async-app-result-removal-migration.md",
222 "description": "Codebase migration to remove error handling from ~500+ callsites",
223 "phases": ["Audit Cross-Boundary Awaits", "Codebase Migration", "Testing and Cleanup"]
224 }
225}