Skip to content

Commit 7e0792f

Browse files
committed
Updates docs to handle async persister case
- Clarifies the concepts to be more relevant to Burr - Adds docs for async persister in the references
1 parent ee6156d commit 7e0792f

File tree

3 files changed

+53
-75
lines changed

3 files changed

+53
-75
lines changed

docs/concepts/index.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ Overview of the concepts -- read these to get a mental model for how Burr works.
2424
additional-visibility
2525
parallelism
2626
recursion
27-
planned-capabilities
2827
sync-vs-async
28+
planned-capabilities

docs/concepts/sync-vs-async.rst

+28-74
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,54 @@ Sync vs Async Applications
44

55
TL;DR
66
------
7-
1. For applications with horizontal scaling: multiple users, lots of i/o throughput,... go with async. Check out:
7+
8+
Burr supports synchronous (standard python) and asynchronous (``async def``/``await``) applications. At a high leveL:
9+
10+
1. Use the `async` interfaces when you have I/O-heavy applications that require horizontal scaling, and have avaialble asynchronous APIs (E.G. async LLM APIs)
811

912
* :py:meth:`.abuild() <.ApplicationBuilder.abuild()>`
1013
* :py:meth:`.aiterate() <.Application.aiterate()>`
1114
* :py:meth:`.arun() <.Application.arun()>`
1215
* :py:meth:`.astream_result() <.Application.astream_result()>`
1316

14-
2. For prototyping applications or high stakes operations,... go with sync.Check out:
17+
2. Use the synchronous interfaces otherwise -- when you have high CPU-bound applications (running models locally), or do not have async APIs to use:
1518

1619
* :py:meth:`.build() <.ApplicationBuilder.build()>`
1720
* :py:meth:`.iterate() <.Application.iterate()>`
1821
* :py:meth:`.run() <.Application.run()>`
1922
* :py:meth:`.stream_result() <.Application.stream_result()>`
2023

24+
Comparison
25+
----------
26+
27+
A synchronous application processes tasks sequentially for every thread/process it executes, blocking entirely on the result
28+
of the prior call. For Burr, this means that two separate applications have to run in a separate thread/process, and that running
29+
parallel processes have to launch in a multithreaded/multi-processing environment, run, and join the results.
30+
31+
In the case of Burr, this means that you have a 1:1 app -> thread/process mapping (unless you're using :ref:`parallelism <parallelism>` and explicitly multithreading sub-actions).
2132

22-
Burr does both sync and async
23-
------------------------------
24-
Bellow we give a short breakdown when to consider each case.
33+
An asynchronous application can parallelize multiple I/O bound tasks within the confines of a single thread. At the time that
34+
a task blocks on I/O it can give control back to the process, allow it to run other tasks simultaneously.
35+
36+
In the case of Burr, this allows you to run more than one applications,in parallel, on the same thread.
37+
Note, however, that you have to ensure the application is async all the way down -- E.G. that every blocking call
38+
is called using `await` -- if it blocks the event loop through a slow, synchronous call, it will block *all* current
39+
applications.
2540

2641
In general, Burr is equipped to handle both synchronous and asynchronous runs. We usually do that by
2742
providing both methods (see specific references for more detail and reach out if you feel like we
28-
are missing a specific implementation).
43+
are missing a specific implementation). Furthermore, Burr suports the following APIs for both synchronous/asynchronous interfaces:
44+
45+
- :ref:`hooks <hooksref>`
46+
- :ref:`persisters <persistersref>`
2947

30-
We hope the switch from one to another is as convenient as possible; you only need to substitute
31-
functions/adapters/method calls.
48+
Nuances of Sync + Async together
49+
--------------------------------
3250

33-
We highly encourage to make a decision to either commit fully to sync or async. Having said that,
51+
We encourage to make a decision to either commit fully to sync or async. That said,
3452
there are cases where a hybrid situation may be desirable or unavoidable (testing, prototyping,
3553
legacy code, ...) and we give some options to handle that. The table bellow shows the
36-
possibilities Burr now supports.
54+
possibilities Burr now supports -- combining the set of synchronous/asynchronous.
3755

3856

3957
.. table:: Cases Burr supports
@@ -73,67 +91,3 @@ possibilities Burr now supports.
7391
| | | should really use the sync |
7492
| | | builder |
7593
+------------------------------------------------+----------+----------------------------------+
76-
77-
78-
Synchronous Applications
79-
--------------------------
80-
A synchronous application processes tasks sequentially, where the user or calling system must wait for
81-
the agent to finish a task before proceeding.
82-
83-
Advantages
84-
~~~~~~~~~~~~
85-
86-
1. Simplicity:
87-
* Easier to design and implement as the logic flows linearly.
88-
* Debugging and maintenance are more straightforward.
89-
2. Deterministic Behavior:
90-
* Results are predictable and occur in a defined sequence.
91-
* Ideal for workflows where steps must be completed in strict order.
92-
3. Low Overhead:
93-
* Useful for tasks that don’t require extensive multitasking or background processing.
94-
* Rapid prototyping.
95-
96-
97-
Use Cases
98-
~~~~~~~~~~~
99-
100-
1. Short, straightforward tasks:
101-
* For example, fetching a single database entry or making a quick calculation.
102-
2. High-stakes operations:
103-
* When the process must proceed step-by-step without the risk of race conditions or overlapping tasks.
104-
3. Interactive applications:
105-
* Situations where the user must receive immediate feedback before taking the next step, like form validations.
106-
107-
Asynchronous Application
108-
--------------------------
109-
An asynchronous application can perform tasks in parallel or handle multiple requests without waiting for
110-
one to finish before starting another.
111-
112-
Advantages
113-
~~~~~~~~~~~~
114-
115-
1. Efficiency:
116-
* Makes better use of system resources by handling multiple tasks simultaneously.
117-
* Reduces idle time, especially when dealing with I/O-bound or network-bound operations.
118-
2. Scalability:
119-
* Handles large volumes of concurrent tasks more effectively.
120-
* Useful in systems requiring high throughput, like web servers or chatbots.
121-
3. Non-blocking Execution:
122-
* Allows other operations to continue while waiting for longer processes to complete.
123-
* Provides a smoother experience in real-time systems.
124-
125-
126-
Use Cases
127-
~~~~~~~~~~~~
128-
129-
1. Long-running processes:
130-
* Training machine learning models.
131-
* Data processing pipelines.
132-
2. I/O-bound tasks:
133-
* Calling APIs.
134-
* Retrieving data from remote servers or databases.
135-
3. High-concurrency systems:
136-
* Chatbots serving multiple users.
137-
* Customer support systems.
138-
4. Background processing:
139-
* Notifications, logs, and analytics tasks running while the main application continues.

docs/reference/persister.rst

+24
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,30 @@ Internally, this interface combines the following two interfaces:
2929

3030
.. automethod:: __init__
3131

32+
Note we also have the corresponding async implementations:
33+
34+
.. autoclass:: burr.core.persistence.AsyncBaseStatePersister
35+
:members:
36+
:show-inheritance:
37+
:inherited-members:
38+
39+
.. automethod:: __init__
40+
41+
Internally, this interface combines the following two interfaces:
42+
43+
.. autoclass:: burr.core.persistence.AsyncBaseStateLoader
44+
:members:
45+
46+
.. automethod:: __init__
47+
48+
.. autoclass:: burr.core.persistence.AsyncBaseStateSaver
49+
:members:
50+
:show-inheritance:
51+
:inherited-members:
52+
53+
.. automethod:: __init__
54+
55+
3256

3357
Supported Sync Implementations
3458
================================

0 commit comments

Comments
 (0)