Skip to content

Conversation

@johnxnguyen
Copy link
Collaborator

@johnxnguyen johnxnguyen commented Oct 28, 2025

BugWPB-20123 [iOS] Invisible groups, channels and 1:1 chats with functioning push notifications

Issue

There is a need to perform tasks asynchronously and automatically, such as fetching conversation metadata for conversations marked as stale, or sending pending messages.

This PR introduces the WorkAgent as a system to generate, schedule, and perform work autonomously. Its design is modeled after ticketing systems common in public places such as banks and town halls where people generate a ticket with a computer system and wait for their ticket to be called. The system will schedule tickets according to priority and available resources and call people when their ticket is ready, who are then able to receive the service they have requested.

The system introduced here works in a similar way:

  1. The WorkAgent is a central object that coordinates Workers, WorkTickets, and a WorkScheduler.
  2. Workers generate tickets and submit them to the WorkAgent.
  3. The agent enqueues the ticket to the scheduler.
  4. While the agent actively running, it will ask the scheduler for the next ticket, then call the associated worker.
  5. The worker, when called, performs the work.

This is a simple an initial implementation to get started, but there are a variety of enhancements that we can make, such as:

  • Handling cancellation: notifying workers tickets have been rejected
  • Handling failed tickets: workers notify failures and suggest recovery options (e.g try again later)
  • Preempting: cancel current tickets to make way for critical tickets
  • Dequeue multiple tickets concurrently: currently one ticket is called at a time, but we could increase this number
  • Smart scheduling based on environment conditions: don't call tickets that require network access if no network available, limit work load if resources (battery, memory) are constrained
  • Add diagnostic metrics: keep track of ticket times, distribution of ticket priority, workloads etc.

Testing

The system is not integrated yet.


Checklist

  • Title contains a reference JIRA issue number like [WPB-XXX].
  • Description is filled and free of optional paragraphs.
  • Adds/updates automated tests.

UI accessibility checklist

If your PR includes UI changes, please utilize this checklist:

  • Make sure you use the API for UI elements that support large fonts.
  • All colors are taken from WireDesign.ColorTheme or constructed using WireDesign.BaseColorPalette.
  • New UI elements have Accessibility strings for VoiceOver.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

Test Results

  2 files  126 suites   23s ⏱️
438 tests 438 ✅ 0 💤 0 ❌
439 runs  439 ✅ 0 💤 0 ❌

Results for commit a856182.

♻️ This comment has been updated with latest results.

Copy link
Collaborator

@netbe netbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a couple comments.

question: why was it added on SyncEngine rather than WireDomain? It would be easier also for integration to initialize on ClientSessionComponent

@johnxnguyen
Copy link
Collaborator Author

johnxnguyen commented Oct 29, 2025

question: why was it added on SyncEngine rather than WireDomain? It would be easier also for integration to initialize on ClientSessionComponent

@netbe I thought maybe it would make sense to keep it closer to the user session but happy to move it to WireDomain.

@johnxnguyen johnxnguyen requested a review from netbe October 29, 2025 09:10
Copy link
Collaborator

@netbe netbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Copy link
Contributor

@samwyndham samwyndham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving because I think this is needed soon but I have some questions that perhaps will be covered in tomorrow's meeting:

  • Currently I don't quite understand where the actually work to be done is contained? I think I need to see an example with real work.
  • Related to above, when reviewing I was kind of wondering is a ticket like a DispatchWorkItem? In the case of a DispatchWorkItem, the work to be done is defined in the item.. But now I'm thinking is the work to be done defined in the Worker? And perhaps a ticket provides information needed to perform the work such as userID? It would be good to see the names of a few possible Workers to understand this better.

@johnxnguyen
Copy link
Collaborator Author

Approving because I think this is needed soon but I have some questions that perhaps will be covered in tomorrow's meeting:

  • Currently I don't quite understand where the actually work to be done is contained? I think I need to see an example with real work.
  • Related to above, when reviewing I was kind of wondering is a ticket like a DispatchWorkItem? In the case of a DispatchWorkItem, the work to be done is defined in the item.. But now I'm thinking is the work to be done defined in the Worker? And perhaps a ticket provides information needed to perform the work such as userID? It would be good to see the names of a few possible Workers to understand this better.

@samwyndham yes you understand right, the work is to be done inside the Worker objects. imagine for example a MessageSenderWorker which is responsible for monitoring the database for unsent messages, raising a ticket for each message found, and when signal by the work agent, to perform the work described in that ticket (i.e send the message).

Another example could be a KeyPackageReplenisher that periodically checks (say once every 24 hours) if new key packages need to be generated and uploaded. Still another examples include "BlacklistChecker", "FeatureConfigFetcher", "ConversationMetadataFetcher".

The idea is that workers know what kind of work they need to do... they are autonomous in this regard, and will raise tickets whenever they want to perform work. But they wait for their ticket to be called in order to proceed with the work. This allows us to keep the work in the workers who have context, while the management and scheduling of the work is done elsewhere that doesn't need to know about the work being done (aside from provided metadata such as priority and requirements like network etc).

@netbe netbe mentioned this pull request Oct 30, 2025
6 tasks
Copy link
Contributor

@jullianm jullianm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work. I left a question/thought

@johnxnguyen johnxnguyen changed the base branch from release/cycle-4.9 to develop November 3, 2025 14:55
@johnxnguyen johnxnguyen enabled auto-merge November 4, 2025 14:06
@johnxnguyen johnxnguyen added this pull request to the merge queue Nov 4, 2025
Merged via the queue into develop with commit ae2835e Nov 4, 2025
10 checks passed
@johnxnguyen johnxnguyen deleted the feat/work-agent branch November 4, 2025 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants