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.
375 lines
14 KiB
HTML
375 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>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="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">scheduler</a></li>
|
|
<li><a href="signal.html" class="active">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>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="scheduler.html" class="prev">scheduler</a>
|
|
<a href="sqlite.html" class="next">sqlite</a>
|
|
</footer>
|
|
</main>
|
|
</div>
|
|
<script src="../js/main.js"></script>
|
|
</body>
|
|
</html>
|