Add three new example scripts demonstrating the fswatch, sysinfo, and udp modules with file watching, system metrics, and UDP echo server/client patterns. Reorder the manual API sidebar navigation to list modules alphabetically, removing deprecated entries like websocket, tls, net, json, regex, jinja, os, signal, subprocess, sqlite, and timer while adding argparse, dataset, fswatch, and html.
312 lines
14 KiB
HTML
312 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<!-- retoor <retoor@molodetz.nl> -->
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>scheduler - Wren-CLI Manual</title>
|
|
<link rel="stylesheet" href="../css/style.css">
|
|
</head>
|
|
<body>
|
|
<button class="mobile-menu-toggle">Menu</button>
|
|
<div class="container">
|
|
<aside class="sidebar">
|
|
<div class="sidebar-header">
|
|
<h1><a href="../index.html">Wren-CLI</a></h1>
|
|
<div class="version">v0.4.0</div>
|
|
</div>
|
|
<nav class="sidebar-nav">
|
|
<div class="section">
|
|
<span class="section-title">Getting Started</span>
|
|
<ul>
|
|
<li><a href="../getting-started/index.html">Overview</a></li>
|
|
<li><a href="../getting-started/installation.html">Installation</a></li>
|
|
<li><a href="../getting-started/first-script.html">First Script</a></li>
|
|
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">Language</span>
|
|
<ul>
|
|
<li><a href="../language/index.html">Syntax Overview</a></li>
|
|
<li><a href="../language/classes.html">Classes</a></li>
|
|
<li><a href="../language/methods.html">Methods</a></li>
|
|
<li><a href="../language/control-flow.html">Control Flow</a></li>
|
|
<li><a href="../language/fibers.html">Fibers</a></li>
|
|
<li><a href="../language/modules.html">Modules</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">API Reference</span>
|
|
<ul>
|
|
<li><a href="index.html">Overview</a></li>
|
|
<li><a href="string.html">String</a></li>
|
|
<li><a href="number.html">Num</a></li>
|
|
<li><a href="argparse.html">argparse</a></li>
|
|
<li><a href="base64.html">base64</a></li>
|
|
<li><a href="crypto.html">crypto</a></li>
|
|
<li><a href="dataset.html">dataset</a></li>
|
|
<li><a href="datetime.html">datetime</a></li>
|
|
<li><a href="dns.html">dns</a></li>
|
|
<li><a href="env.html">env</a></li>
|
|
<li><a href="fswatch.html">fswatch</a></li>
|
|
<li><a href="html.html">html</a></li>
|
|
<li><a href="http.html">http</a></li>
|
|
<li><a href="io.html">io</a></li>
|
|
<li><a href="jinja.html">jinja</a></li>
|
|
<li><a href="json.html">json</a></li>
|
|
<li><a href="markdown.html">markdown</a></li>
|
|
<li><a href="math.html">math</a></li>
|
|
<li><a href="net.html">net</a></li>
|
|
<li><a href="os.html">os</a></li>
|
|
<li><a href="pathlib.html">pathlib</a></li>
|
|
<li><a href="regex.html">regex</a></li>
|
|
<li><a href="scheduler.html" class="active">scheduler</a></li>
|
|
<li><a href="signal.html">signal</a></li>
|
|
<li><a href="sqlite.html">sqlite</a></li>
|
|
<li><a href="subprocess.html">subprocess</a></li>
|
|
<li><a href="sysinfo.html">sysinfo</a></li>
|
|
<li><a href="tempfile.html">tempfile</a></li>
|
|
<li><a href="timer.html">timer</a></li>
|
|
<li><a href="tls.html">tls</a></li>
|
|
<li><a href="udp.html">udp</a></li>
|
|
<li><a href="uuid.html">uuid</a></li>
|
|
<li><a href="wdantic.html">wdantic</a></li>
|
|
<li><a href="web.html">web</a></li>
|
|
<li><a href="websocket.html">websocket</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">Tutorials</span>
|
|
<ul>
|
|
<li><a href="../tutorials/index.html">Tutorial List</a></li>
|
|
<li><a href="../tutorials/http-client.html">HTTP Client</a></li>
|
|
<li><a href="../tutorials/websocket-chat.html">WebSocket Chat</a></li>
|
|
<li><a href="../tutorials/database-app.html">Database App</a></li>
|
|
<li><a href="../tutorials/template-rendering.html">Templates</a></li>
|
|
<li><a href="../tutorials/cli-tool.html">CLI Tool</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="section">
|
|
<span class="section-title">How-To Guides</span>
|
|
<ul>
|
|
<li><a href="../howto/index.html">How-To List</a></li>
|
|
<li><a href="../howto/http-requests.html">HTTP Requests</a></li>
|
|
<li><a href="../howto/json-parsing.html">JSON Parsing</a></li>
|
|
<li><a href="../howto/regex-patterns.html">Regex Patterns</a></li>
|
|
<li><a href="../howto/file-operations.html">File Operations</a></li>
|
|
<li><a href="../howto/async-operations.html">Async Operations</a></li>
|
|
<li><a href="../howto/error-handling.html">Error Handling</a></li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
</aside>
|
|
<main class="content">
|
|
<nav class="breadcrumb">
|
|
<a href="../index.html">Home</a>
|
|
<span class="separator">/</span>
|
|
<a href="index.html">API Reference</a>
|
|
<span class="separator">/</span>
|
|
<span>scheduler</span>
|
|
</nav>
|
|
|
|
<article>
|
|
<h1>scheduler</h1>
|
|
|
|
<p>The <code>scheduler</code> module manages the async event loop and fiber scheduling. It is the foundation for all async operations in Wren-CLI.</p>
|
|
|
|
<pre><code>import "scheduler" for Scheduler</code></pre>
|
|
|
|
<h2>Scheduler Class</h2>
|
|
|
|
<div class="class-header">
|
|
<h3>Scheduler</h3>
|
|
<p>Async fiber scheduler</p>
|
|
</div>
|
|
|
|
<h3>Static Methods</h3>
|
|
|
|
<div class="method-signature">
|
|
<span class="method-name">Scheduler.await_</span>(<span class="param">block</span>) → <span class="type">any</span>
|
|
</div>
|
|
<p>Suspends the current fiber until an async operation completes. Used internally by modules to implement async operations.</p>
|
|
<ul class="param-list">
|
|
<li><span class="param-name">block</span> <span class="param-type">(Fn)</span> - Block that initiates the async operation</li>
|
|
<li><span class="returns">Returns:</span> Result of the async operation</li>
|
|
</ul>
|
|
<pre><code>var result = Scheduler.await_ {
|
|
Timer.sleep_(1000, Fiber.current)
|
|
}</code></pre>
|
|
|
|
<div class="method-signature">
|
|
<span class="method-name">Scheduler.resume_</span>(<span class="param">fiber</span>)
|
|
</div>
|
|
<p>Resumes a suspended fiber. Used by native code to wake up fibers when async operations complete.</p>
|
|
|
|
<div class="method-signature">
|
|
<span class="method-name">Scheduler.resume_</span>(<span class="param">fiber</span>, <span class="param">value</span>)
|
|
</div>
|
|
<p>Resumes a fiber with a result value.</p>
|
|
|
|
<h2 id="await-syntax">Await Syntax</h2>
|
|
|
|
<p>Wren-CLI provides a convenient syntax for awaiting async functions. Instead of using <code>.call()</code>, you can call async functions directly after <code>await</code>:</p>
|
|
|
|
<h3>Before and After</h3>
|
|
<pre><code>// Old syntax (still works)
|
|
var result = await asyncFn.call(arg1, arg2)
|
|
|
|
// New syntax (recommended)
|
|
var result = await asyncFn(arg1, arg2)</code></pre>
|
|
|
|
<p>The compiler automatically translates <code>await fn(args)</code> to <code>await fn.call(args)</code>.</p>
|
|
|
|
<h3>Supported Patterns</h3>
|
|
|
|
<table class="params-table">
|
|
<thead>
|
|
<tr><th>Pattern</th><th>Example</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td>No arguments</td><td><code>await getValue()</code></td></tr>
|
|
<tr><td>Single argument</td><td><code>await double(21)</code></td></tr>
|
|
<tr><td>Multiple arguments</td><td><code>await add(3, 4, 5)</code></td></tr>
|
|
<tr><td>Nested awaits</td><td><code>await outer(await inner(x))</code></td></tr>
|
|
<tr><td>In expressions</td><td><code>var x = 1 + await fn(2)</code></td></tr>
|
|
<tr><td>In conditions</td><td><code>if (await check(x)) { }</code></td></tr>
|
|
<tr><td>Block argument</td><td><code>await map(list) { |x| x * 2 }</code></td></tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="admonition note">
|
|
<div class="admonition-title">Note</div>
|
|
<p>Method chaining after <code>await fn(args)</code> requires assigning the result first:</p>
|
|
<pre><code>var list = await getList(5)
|
|
System.print(list.count)</code></pre>
|
|
</div>
|
|
|
|
<h3>Examples</h3>
|
|
|
|
<pre><code>import "scheduler" for Scheduler, Future
|
|
|
|
var double = async { |x| x * 2 }
|
|
var add = async { |a, b| a + b }
|
|
|
|
// Basic usage
|
|
System.print(await double(21)) // 42
|
|
System.print(await add(3, 4)) // 7
|
|
|
|
// Nested awaits
|
|
var result = await double(await add(5, 5)) // 20
|
|
|
|
// Method chaining
|
|
var getList = async { |n| [1, 2, 3, n] }
|
|
System.print(await getList(4).count) // 4
|
|
|
|
// In expressions
|
|
var total = await add(10, 20) + await double(5) // 40</code></pre>
|
|
|
|
<h3>Class-Based Async Patterns</h3>
|
|
|
|
<p>Static getters that return async functions must first be assigned to a variable:</p>
|
|
|
|
<pre><code>import "scheduler" for Scheduler, Future
|
|
|
|
class Calculator {
|
|
static add { async { |a, b| a + b } }
|
|
static multiply { async { |a, b| a * b } }
|
|
static square { async { |x| x * x } }
|
|
|
|
static compute(a, b) {
|
|
var addFn = Calculator.add
|
|
var multiplyFn = Calculator.multiply
|
|
var sum = await addFn(a, b)
|
|
var product = await multiplyFn(a, b)
|
|
return [sum, product]
|
|
}
|
|
}
|
|
|
|
// Assign getter to variable first, then await
|
|
var add = Calculator.add
|
|
System.print(await add(3, 4)) // 7
|
|
|
|
var multiply = Calculator.multiply
|
|
System.print(await multiply(5, 6)) // 30
|
|
|
|
var square = Calculator.square
|
|
System.print(await square(8)) // 64</code></pre>
|
|
|
|
<div class="admonition note">
|
|
<div class="admonition-title">Note</div>
|
|
<p>The <code>fn(args)</code> syntax only works directly after <code>await</code>. Outside of <code>await</code>, use <code>fn.call(args)</code> to invoke async functions.</p>
|
|
</div>
|
|
|
|
<h2>How Async Works</h2>
|
|
|
|
<p>Wren-CLI uses an event loop (libuv) for non-blocking I/O. Here is how async operations work:</p>
|
|
|
|
<ol>
|
|
<li>A Wren fiber calls an async method (e.g., <code>Http.get</code>)</li>
|
|
<li>The method starts a native async operation and suspends the fiber</li>
|
|
<li>The event loop continues processing other events</li>
|
|
<li>When the operation completes, the fiber is resumed with the result</li>
|
|
</ol>
|
|
|
|
<h3>Under the Hood</h3>
|
|
<pre><code>// How Timer.sleep works internally
|
|
class Timer {
|
|
static sleep(ms) {
|
|
return Scheduler.await_ {
|
|
Timer.sleep_(ms, Fiber.current)
|
|
}
|
|
}
|
|
|
|
foreign static sleep_(ms, fiber)
|
|
}</code></pre>
|
|
|
|
<h2>Examples</h2>
|
|
|
|
<h3>Sequential vs Parallel</h3>
|
|
<p>Operations are sequential by default:</p>
|
|
<pre><code>import "http" for Http
|
|
|
|
// These run one after another (sequential)
|
|
var r1 = Http.get("https://api.example.com/1")
|
|
var r2 = Http.get("https://api.example.com/2")
|
|
var r3 = Http.get("https://api.example.com/3")</code></pre>
|
|
|
|
<p>For parallel operations, use multiple fibers:</p>
|
|
<pre><code>import "http" for Http
|
|
|
|
var fibers = [
|
|
Fiber.new { Http.get("https://api.example.com/1") },
|
|
Fiber.new { Http.get("https://api.example.com/2") },
|
|
Fiber.new { Http.get("https://api.example.com/3") }
|
|
]
|
|
|
|
// Start all fibers
|
|
for (f in fibers) f.call()
|
|
|
|
// Results are already available when fibers complete</code></pre>
|
|
|
|
<div class="admonition note">
|
|
<div class="admonition-title">Note</div>
|
|
<p>The scheduler is used internally by modules. Most user code does not need to interact with it directly. Use higher-level modules like <code>timer</code>, <code>http</code>, and <code>io</code> instead.</p>
|
|
</div>
|
|
|
|
<div class="admonition tip">
|
|
<div class="admonition-title">Tip</div>
|
|
<p>Async operations in Wren-CLI are cooperative, not preemptive. A fiber runs until it explicitly yields or calls an async operation.</p>
|
|
</div>
|
|
</article>
|
|
|
|
<footer class="page-footer">
|
|
<a href="pathlib.html" class="prev">pathlib</a>
|
|
<a href="math.html" class="next">math</a>
|
|
</footer>
|
|
</main>
|
|
</div>
|
|
<script src="../js/main.js"></script>
|
|
</body>
|
|
</html>
|