-
Notifications
You must be signed in to change notification settings - Fork 198
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin' into releases/rc-trulens-1.2.9
- Loading branch information
Showing
15 changed files
with
814 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# This notebook demonstrates how to use the Pace utility\n", | ||
"\n", | ||
"This utility can be used to limit the rate of API requests to external endpoints. " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import asyncio\n", | ||
"import random\n", | ||
"import threading\n", | ||
"import time\n", | ||
"\n", | ||
"from IPython import display\n", | ||
"from trulens.core.utils.pace import Pace" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Create a pace instance with 2 second per period and 20 marks per second. The\n", | ||
"# average of 20 marks per second will be maintained across any 2 second period\n", | ||
"# but this makes it possible for an initial burst of 20 marks immediately. This\n", | ||
"# is due to the assumption that there were no marks before the process started.\n", | ||
"\n", | ||
"# If seconds_per_period is increased, a larger burst of marks will be possible\n", | ||
"# before the average marks per second since the start of the process stabilizes.\n", | ||
"# A larger burst also means there will be a delay until the next period before\n", | ||
"# marks can return again. A \"burstiness\" warning is issue the first time a delay\n", | ||
"# longer than half of the seconds_per_period is encountered.\n", | ||
"\n", | ||
"p = Pace(seconds_per_period=2, marks_per_second=20)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# start time and counter\n", | ||
"st = time.time()\n", | ||
"count = 0\n", | ||
"\n", | ||
"while True:\n", | ||
" # Mark and increment counter. Calls to mark will block to maintain pace.\n", | ||
" p.mark()\n", | ||
" count += 1\n", | ||
"\n", | ||
" et = time.time()\n", | ||
" display.clear_output(wait=True)\n", | ||
"\n", | ||
" # Show stats of the marks rate since the start of this cell.\n", | ||
" print(f\"\"\"\n", | ||
"Elapsed time: {et - st}\n", | ||
"Marks count: {count}\n", | ||
"Marks per second: {count / (et - st)}\n", | ||
"\"\"\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Pace across Threads\n", | ||
"\n", | ||
"The pacing should be maintained even if a single Pace instance is used across\n", | ||
"multiple threads." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"num_threads = 10\n", | ||
"count = 0\n", | ||
"\n", | ||
"\n", | ||
"# Create a function to run in each thread and update the count for each mark:\n", | ||
"def marker():\n", | ||
" global count\n", | ||
"\n", | ||
" while True:\n", | ||
" # Mark and increment counter. Calls to mark will block to maintain pace.\n", | ||
" p.mark()\n", | ||
" count += 1\n", | ||
"\n", | ||
" # Add a bit of sleep to simulate some work.\n", | ||
" time.sleep(random.random() / 100.0)\n", | ||
"\n", | ||
"\n", | ||
"# Start time.\n", | ||
"st = time.time()\n", | ||
"\n", | ||
"# Start the threads.\n", | ||
"for i in range(num_threads):\n", | ||
" t = threading.Thread(target=marker)\n", | ||
" t.start()\n", | ||
"\n", | ||
"while True:\n", | ||
" # Report count stats every second.\n", | ||
" time.sleep(1)\n", | ||
"\n", | ||
" display.clear_output(wait=True)\n", | ||
"\n", | ||
" et = time.time()\n", | ||
"\n", | ||
" # Show stats of the marks rate since the start of this cell.\n", | ||
" print(f\"\"\"\n", | ||
"Elapsed time: {et - st}\n", | ||
"Marks count: {count}\n", | ||
"Marks per second: {count / (et - st)}\n", | ||
"\"\"\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Pace in Async Tasks\n", | ||
"\n", | ||
"Pace can also be maintained when using asynchronous tasks. For this, the `amark`\n", | ||
"method must be used and awaited." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"num_tasks = 10\n", | ||
"count = 0\n", | ||
"\n", | ||
"\n", | ||
"# Create a function to run in each task and update the count for each mark:\n", | ||
"async def async_marker():\n", | ||
" global count\n", | ||
"\n", | ||
" while True:\n", | ||
" # Mark and increment counter. Calls to amark will block to maintain pace.\n", | ||
" await p.amark()\n", | ||
" count += 1\n", | ||
"\n", | ||
" # Add a bit of sleep to simulate some work.\n", | ||
" await asyncio.sleep(random.random() / 100.0)\n", | ||
"\n", | ||
"\n", | ||
"# Start time.\n", | ||
"st = time.time()\n", | ||
"\n", | ||
"loop = asyncio.get_event_loop()\n", | ||
"\n", | ||
"# Start the threads.\n", | ||
"for i in range(num_tasks):\n", | ||
" task = loop.create_task(async_marker())\n", | ||
"\n", | ||
"while True:\n", | ||
" # Report count stats every second.\n", | ||
"\n", | ||
" await asyncio.sleep(1)\n", | ||
"\n", | ||
" display.clear_output(wait=True)\n", | ||
"\n", | ||
" et = time.time()\n", | ||
"\n", | ||
" # Show stats of the marks rate since the start of this cell.\n", | ||
" print(f\"\"\"\n", | ||
"max_marks: {p.max_marks}\n", | ||
"mark_expirations: {p.mark_expirations}\n", | ||
"len(mark_expirations): {len(p.mark_expirations)}\n", | ||
"Elapsed time: {et - st}\n", | ||
"Marks count: {count}\n", | ||
"Marks per second: {count / (et - st)}\n", | ||
"\"\"\")" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.