feat: add example scripts for argparse, bytes, dataset, html, markdown, uuid, wdantic, and web chat modules
Add comprehensive demo scripts showcasing the usage of multiple Wren modules including argument parsing, byte manipulation, in-memory dataset operations, HTML encoding/slugification, markdown-to-HTML conversion, UUID generation/validation, schema validation with wdantic, and a full web chat application with REST endpoints.
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
<!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>signal - 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="http.html">http</a></li>
|
||||
<li><a href="websocket.html">websocket</a></li>
|
||||
<li><a href="tls.html">tls</a></li>
|
||||
<li><a href="net.html">net</a></li>
|
||||
<li><a href="dns.html">dns</a></li>
|
||||
<li><a href="json.html">json</a></li>
|
||||
<li><a href="base64.html">base64</a></li>
|
||||
<li><a href="regex.html">regex</a></li>
|
||||
<li><a href="jinja.html">jinja</a></li>
|
||||
<li><a href="crypto.html">crypto</a></li>
|
||||
<li><a href="os.html">os</a></li>
|
||||
<li><a href="env.html">env</a></li>
|
||||
<li><a href="signal.html" class="active">signal</a></li>
|
||||
<li><a href="subprocess.html">subprocess</a></li>
|
||||
<li><a href="sqlite.html">sqlite</a></li>
|
||||
<li><a href="datetime.html">datetime</a></li>
|
||||
<li><a href="timer.html">timer</a></li>
|
||||
<li><a href="io.html">io</a></li>
|
||||
<li><a href="scheduler.html">scheduler</a></li>
|
||||
<li><a href="math.html">math</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<span class="section-title">Tutorials</span>
|
||||
<ul>
|
||||
<li><a href="../tutorials/index.html">Tutorial List</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>
|
||||
</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>signal</span>
|
||||
</nav>
|
||||
|
||||
<article>
|
||||
<h1>signal</h1>
|
||||
|
||||
<p>The <code>signal</code> module provides Unix signal handling capabilities, allowing scripts to trap, ignore, or reset signal handlers.</p>
|
||||
|
||||
<pre><code>import "signal" for Signal</code></pre>
|
||||
|
||||
<h2>Signal Class</h2>
|
||||
|
||||
<div class="class-header">
|
||||
<h3>Signal</h3>
|
||||
<p>Unix signal handling</p>
|
||||
</div>
|
||||
|
||||
<h3>Signal Constants</h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Constant</th>
|
||||
<th>Value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Signal.SIGHUP</code></td>
|
||||
<td>1</td>
|
||||
<td>Hangup (terminal closed or controlling process ended)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Signal.SIGINT</code></td>
|
||||
<td>2</td>
|
||||
<td>Interrupt (Ctrl+C)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Signal.SIGQUIT</code></td>
|
||||
<td>3</td>
|
||||
<td>Quit (Ctrl+\)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Signal.SIGTERM</code></td>
|
||||
<td>15</td>
|
||||
<td>Termination request</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Signal.SIGUSR1</code></td>
|
||||
<td>10</td>
|
||||
<td>User-defined signal 1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>Signal.SIGUSR2</code></td>
|
||||
<td>12</td>
|
||||
<td>User-defined signal 2</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Static Methods</h3>
|
||||
|
||||
<div class="method-signature">
|
||||
<span class="method-name">Signal.trap</span>(<span class="param">signum</span>, <span class="param">fn</span>)
|
||||
</div>
|
||||
<p>Registers a handler function to be called when the signal is received. The handler will be called each time the signal is received.</p>
|
||||
<ul class="param-list">
|
||||
<li><span class="param-name">signum</span> <span class="param-type">(Num)</span> - Signal number or constant</li>
|
||||
<li><span class="param-name">fn</span> <span class="param-type">(Fn)</span> - Handler function (no arguments)</li>
|
||||
</ul>
|
||||
<pre><code>Signal.trap(Signal.SIGINT) {
|
||||
System.print("Caught Ctrl+C!")
|
||||
}</code></pre>
|
||||
|
||||
<div class="method-signature">
|
||||
<span class="method-name">Signal.ignore</span>(<span class="param">signum</span>)
|
||||
</div>
|
||||
<p>Ignores the specified signal. The signal will be delivered but have no effect.</p>
|
||||
<ul class="param-list">
|
||||
<li><span class="param-name">signum</span> <span class="param-type">(Num)</span> - Signal number to ignore</li>
|
||||
</ul>
|
||||
<pre><code>Signal.ignore(Signal.SIGHUP)</code></pre>
|
||||
|
||||
<div class="method-signature">
|
||||
<span class="method-name">Signal.reset</span>(<span class="param">signum</span>)
|
||||
</div>
|
||||
<p>Resets the signal handler to the default behavior.</p>
|
||||
<ul class="param-list">
|
||||
<li><span class="param-name">signum</span> <span class="param-type">(Num)</span> - Signal number to reset</li>
|
||||
</ul>
|
||||
<pre><code>Signal.reset(Signal.SIGINT)</code></pre>
|
||||
|
||||
<h2>Examples</h2>
|
||||
|
||||
<h3>Graceful Shutdown</h3>
|
||||
<pre><code>import "signal" for Signal
|
||||
import "timer" for Timer
|
||||
|
||||
var running = true
|
||||
|
||||
Signal.trap(Signal.SIGINT) {
|
||||
System.print("\nShutting down gracefully...")
|
||||
running = false
|
||||
}
|
||||
|
||||
Signal.trap(Signal.SIGTERM) {
|
||||
System.print("\nReceived SIGTERM, shutting down...")
|
||||
running = false
|
||||
}
|
||||
|
||||
System.print("Server running. Press Ctrl+C to stop.")
|
||||
while (running) {
|
||||
Timer.sleep(1000)
|
||||
}
|
||||
|
||||
System.print("Cleanup complete. Goodbye!")</code></pre>
|
||||
|
||||
<h3>Configuration Reload on SIGHUP</h3>
|
||||
<pre><code>import "signal" for Signal
|
||||
import "timer" for Timer
|
||||
import "io" for File
|
||||
|
||||
var config = {}
|
||||
|
||||
var loadConfig = Fn.new {
|
||||
System.print("Loading configuration...")
|
||||
if (File.exists("config.json")) {
|
||||
var content = File.read("config.json")
|
||||
System.print("Config loaded: %(content)")
|
||||
}
|
||||
}
|
||||
|
||||
loadConfig.call()
|
||||
|
||||
Signal.trap(Signal.SIGHUP) {
|
||||
System.print("Received SIGHUP, reloading config...")
|
||||
loadConfig.call()
|
||||
}
|
||||
|
||||
System.print("Running. Send SIGHUP to reload config.")
|
||||
while (true) {
|
||||
Timer.sleep(1000)
|
||||
}</code></pre>
|
||||
|
||||
<h3>Custom Signal for Debug Dump</h3>
|
||||
<pre><code>import "signal" for Signal
|
||||
import "timer" for Timer
|
||||
import "datetime" for DateTime
|
||||
|
||||
var requestCount = 0
|
||||
var startTime = DateTime.now()
|
||||
|
||||
Signal.trap(Signal.SIGUSR1) {
|
||||
System.print("=== Debug Dump ===")
|
||||
System.print("Requests handled: %(requestCount)")
|
||||
var uptime = DateTime.now() - startTime
|
||||
System.print("Uptime: %(uptime.hours) hours")
|
||||
System.print("==================")
|
||||
}
|
||||
|
||||
System.print("Send SIGUSR1 for debug info (kill -USR1 pid)")
|
||||
while (true) {
|
||||
requestCount = requestCount + 1
|
||||
Timer.sleep(100)
|
||||
}</code></pre>
|
||||
|
||||
<h3>Ignoring Signals</h3>
|
||||
<pre><code>import "signal" for Signal
|
||||
import "timer" for Timer
|
||||
|
||||
Signal.ignore(Signal.SIGINT)
|
||||
System.print("SIGINT is now ignored. Ctrl+C will not stop this script.")
|
||||
System.print("Use 'kill -9 pid' to force stop.")
|
||||
|
||||
for (i in 1..10) {
|
||||
System.print("Still running... %(i)")
|
||||
Timer.sleep(1000)
|
||||
}
|
||||
|
||||
Signal.reset(Signal.SIGINT)
|
||||
System.print("SIGINT handler restored. Ctrl+C works again.")</code></pre>
|
||||
|
||||
<h3>Multiple Signal Handlers</h3>
|
||||
<pre><code>import "signal" for Signal
|
||||
import "timer" for Timer
|
||||
|
||||
var shutdownRequested = false
|
||||
var forceShutdown = false
|
||||
|
||||
Signal.trap(Signal.SIGINT) {
|
||||
if (shutdownRequested) {
|
||||
System.print("\nForce shutdown!")
|
||||
forceShutdown = true
|
||||
} else {
|
||||
System.print("\nGraceful shutdown requested. Press Ctrl+C again to force.")
|
||||
shutdownRequested = true
|
||||
}
|
||||
}
|
||||
|
||||
Signal.trap(Signal.SIGTERM) {
|
||||
System.print("\nSIGTERM received, shutting down immediately.")
|
||||
forceShutdown = true
|
||||
}
|
||||
|
||||
System.print("Running... Press Ctrl+C to stop.")
|
||||
while (!forceShutdown) {
|
||||
if (shutdownRequested) {
|
||||
System.print("Cleaning up...")
|
||||
Timer.sleep(500)
|
||||
break
|
||||
}
|
||||
Timer.sleep(100)
|
||||
}
|
||||
|
||||
System.print("Exited.")</code></pre>
|
||||
|
||||
<h3>Worker Process Control</h3>
|
||||
<pre><code>import "signal" for Signal
|
||||
import "timer" for Timer
|
||||
|
||||
var paused = false
|
||||
|
||||
Signal.trap(Signal.SIGUSR1) {
|
||||
paused = true
|
||||
System.print("Worker paused")
|
||||
}
|
||||
|
||||
Signal.trap(Signal.SIGUSR2) {
|
||||
paused = false
|
||||
System.print("Worker resumed")
|
||||
}
|
||||
|
||||
System.print("Worker running. SIGUSR1 to pause, SIGUSR2 to resume.")
|
||||
|
||||
var count = 0
|
||||
while (true) {
|
||||
if (!paused) {
|
||||
count = count + 1
|
||||
System.print("Working... %(count)")
|
||||
}
|
||||
Timer.sleep(1000)
|
||||
}</code></pre>
|
||||
|
||||
<div class="admonition note">
|
||||
<div class="admonition-title">Note</div>
|
||||
<p>Signal handling is only available on POSIX systems (Linux, macOS, BSD). On Windows, signal support is limited.</p>
|
||||
</div>
|
||||
|
||||
<div class="admonition warning">
|
||||
<div class="admonition-title">Warning</div>
|
||||
<p>Some signals like SIGKILL (9) and SIGSTOP (19) cannot be trapped or ignored. Attempting to do so will have no effect.</p>
|
||||
</div>
|
||||
|
||||
<div class="admonition tip">
|
||||
<div class="admonition-title">Tip</div>
|
||||
<p>Always implement graceful shutdown handlers for long-running services. Use SIGTERM for clean shutdowns and reserve SIGINT for interactive termination.</p>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<footer class="page-footer">
|
||||
<a href="env.html" class="prev">env</a>
|
||||
<a href="subprocess.html" class="next">subprocess</a>
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
<script src="../js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user