Skip to content

Commit e99b317

Browse files
committed
Integrate async-container-supervisor.
1 parent be54958 commit e99b317

File tree

16 files changed

+228
-231
lines changed

16 files changed

+228
-231
lines changed

bake/falcon/supervisor.rb

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,5 @@
44
# Copyright, 2020-2025, by Samuel Williams.
55

66
def restart
7-
require_relative "../../lib/falcon/command/supervisor"
8-
9-
Falcon::Command::Supervisor["restart"].call
7+
context.lookup("async:container:supervisor:restart").call
108
end

examples/benchmark/small.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export const options = {
2+
stages: [
3+
// Warmup: Gradually ramp up:
4+
{duration: '10s', target: 64},
5+
6+
// Main test: Sustained load:
7+
{duration: '1m', target: 64},
8+
],
9+
};
10+
11+
import http from 'k6/http';
12+
import { check, sleep } from 'k6';
13+
14+
export default function () {
15+
const res = http.get('http://localhost:9292/small');
16+
17+
check(res, {
18+
'is status 200': (r) => r.status === 200,
19+
'response time < 200ms': (r) => r.timings.duration < 200,
20+
});
21+
}

examples/dungeons/Modelfile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM llama2
2+
# sets the temperature to 1 [higher is more creative, lower is more coherent]
3+
PARAMETER temperature 1
4+
# sets the context window size to 4096, this controls how many tokens the LLM can use as context to generate the next token
5+
PARAMETER num_ctx 4096
6+
7+
# sets a custom system message to specify the behavior of the chat assistant
8+
SYSTEM You find yourself at the entrance to a dungeon. What do you do next?
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
FROM llama2:13b
2+
3+
PARAMETER num_ctx 16384
4+
5+
SYSTEM """
6+
You are an entity in a role playing game. You will receive input from the game world and must respond with actions. Input from the game world will include nearby events and dialogue. You can perform one or more actions include speaking, moving and using things in the world. You must ONLY respond with actions in the specified format otherwise the game will respond with ERROR to inform you that the input was not understood, and you should try again using one of the defined actions.
7+
8+
Inputs will be formatted in the following way:
9+
10+
TIME [time]
11+
The game world has advanced to the specified time.
12+
SEE [entity] [distance] [action]
13+
You see something.
14+
HEAR [entity] [distance] [dialogue]
15+
You hear something.
16+
ARRIVE [entity]
17+
You arrive somewhere.
18+
ERROR [message]
19+
Your action was not understood (perhaps try again).
20+
21+
Actions must be formatted in the following way:
22+
23+
MOVE TOWARDS [entity]
24+
You will begin moving towards the named entity.
25+
SPEAK "dialogue"
26+
You will speak the specified dialogue.
27+
USE [entity]
28+
You will use the named entity.
29+
LOOK
30+
You will look around and the game will inform you of nearby entities.
31+
PASS
32+
Do nothing.
33+
34+
Before you try to interact with things, ensure you LOOK to see what is available. Then, MOVE TOWARDS the entity. Finally the game world will inform you when you ARRIVE at the entity. You may perform more than one action at a time if you list them on separate lines.
35+
36+
The entity you are simulating is a cat.
37+
"""

examples/hello-event/scheduler.rb

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2021-2023, by Samuel Williams.
5+
6+
$LOAD_PATH << File.expand_path("../../lib", __dir__)
7+
$LOAD_PATH << File.expand_path("../../ext", __dir__)
8+
9+
require "io/event"
10+
11+
require "socket"
12+
require "fiber"
13+
14+
class Scheduler
15+
def initialize(selector = nil)
16+
@fiber = Fiber.current
17+
@selector = selector || IO::Event::Selector.new(@fiber)
18+
@pending = []
19+
@waiting = {}
20+
21+
unless @selector.respond_to?(:io_close)
22+
instance_eval{undef io_close}
23+
end
24+
25+
@mutex = Mutex.new
26+
end
27+
28+
def block(blocker, timeout)
29+
raise NotImplementedError
30+
end
31+
32+
def unblock(blocker, fiber)
33+
raise NotImplementedError
34+
end
35+
36+
def io_wait(io, events, timeout)
37+
fiber = Fiber.current
38+
@waiting[fiber] = io
39+
@selector.io_wait(fiber, io, events)
40+
ensure
41+
@waiting.delete(fiber)
42+
end
43+
44+
def io_close(io)
45+
@selector.io_close(io)
46+
end
47+
48+
def kernel_sleep(duration)
49+
@selector.defer
50+
end
51+
52+
def close
53+
while @selector.ready? || @waiting.any?
54+
begin
55+
@selector.select(nil)
56+
rescue Errno::EINTR
57+
# Ignore.
58+
end
59+
end
60+
rescue Interrupt
61+
# Exit.
62+
end
63+
64+
def fiber(&block)
65+
fiber = Fiber.new(&block)
66+
67+
@selector.resume(fiber)
68+
69+
return fiber
70+
end
71+
end
72+
73+
class DirectScheduler < Scheduler
74+
def io_read(io, buffer, length)
75+
fiber = Fiber.current
76+
@waiting[fiber] = io
77+
result = @selector.io_read(fiber, io, buffer, length)
78+
ensure
79+
@waiting.delete(fiber)
80+
end
81+
82+
def io_write(io, buffer, length)
83+
fiber = Fiber.current
84+
@waiting[fiber] = io
85+
@selector.io_write(fiber, io, buffer, length)
86+
ensure
87+
@waiting.delete(fiber)
88+
end
89+
end

examples/hello-event/server.rb

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
# Released under the MIT License.
5+
# Copyright, 2021-2023, by Samuel Williams.
6+
7+
require_relative "scheduler"
8+
require "io/nonblock"
9+
10+
#scheduler = DirectScheduler.new
11+
scheduler = Scheduler.new
12+
Fiber.set_scheduler(scheduler)
13+
14+
port = Integer(ARGV.pop || 3020)
15+
16+
RESPONSE = "HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nHello World"
17+
18+
Fiber.schedule do
19+
server = TCPServer.new("localhost", port)
20+
server.listen(Socket::SOMAXCONN)
21+
22+
loop do
23+
peer, address = server.accept
24+
25+
Fiber.schedule do
26+
while request_line = peer.readpartial(1024) rescue nil
27+
peer.write(RESPONSE)
28+
end
29+
ensure
30+
peer.close
31+
end
32+
end
33+
end

examples/hello/falcon.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
# append preload "preload.rb"
2323

24-
24+
include Async::Container::Supervisor::Supervised
2525
end
2626

2727
service "supervisor" do

falcon.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ Gem::Specification.new do |spec|
2828

2929
spec.add_dependency "async"
3030
spec.add_dependency "async-container", "~> 0.20"
31+
spec.add_dependency "async-container-supervisor", "~> 0.4.0"
3132
spec.add_dependency "async-http", "~> 0.75"
3233
spec.add_dependency "async-http-cache", "~> 0.4"
3334
spec.add_dependency "async-service", "~> 0.10"
3435
spec.add_dependency "bundler"
3536
spec.add_dependency "localhost", "~> 1.1"
3637
spec.add_dependency "openssl", "~> 3.0"
37-
spec.add_dependency "process-metrics", "~> 0.2"
3838
spec.add_dependency "protocol-http", "~> 0.31"
3939
spec.add_dependency "protocol-rack", "~> 0.7"
4040
spec.add_dependency "samovar", "~> 2.3"

gems.rb

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# gem "async-http", path: "../async-http-native-io"
1212
# gem "openssl", git: "https://github.com/ruby/openssl.git"
1313
# gem "async-container", path: "../async-container"
14+
gem "async-container-supervisor", path: "../async-container-supervisor"
1415
# gem "async-websocket", path: "../async-websocket"
1516
# gem "async-http", path: "../async-http"
1617
# gem "async-http-cache", path: "../async-http-cache"

lib/falcon/command/supervisor.rb

-73
This file was deleted.

lib/falcon/command/top.rb

-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
require_relative "virtual"
99
require_relative "proxy"
1010
require_relative "redirect"
11-
require_relative "supervisor"
1211

1312
require_relative "../version"
1413

@@ -38,7 +37,6 @@ class Top < Samovar::Command
3837
"virtual" => Virtual,
3938
"proxy" => Proxy,
4039
"redirect" => Redirect,
41-
"supervisor" => Supervisor,
4240
}, default: "serve"
4341

4442
# Whether verbose logging is enabled.

lib/falcon/environment/supervisor.rb

+4-22
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,24 @@
33
# Released under the MIT License.
44
# Copyright, 2019-2024, by Samuel Williams.
55

6-
require_relative "../service/supervisor"
76
require_relative "../environment"
87

9-
require "io/endpoint/unix_endpoint"
8+
require "async/container/supervisor"
109

1110
module Falcon
1211
module Environment
1312
# Provides an environment for hosting a supervisor which can monitor multiple applications.
1413
module Supervisor
15-
# The service class to use for the supervisor.
16-
# @returns [Class]
17-
def service_class
18-
::Falcon::Service::Supervisor
19-
end
20-
21-
# The name of the supervisor
22-
# @returns [String]
23-
def name
24-
"supervisor"
25-
end
14+
include Async::Container::Supervisor::Environment
2615

2716
# The IPC path to use for communication with the supervisor.
2817
# @returns [String]
2918
def ipc_path
3019
::File.expand_path("supervisor.ipc", root)
3120
end
3221

33-
# The endpoint the supervisor will bind to.
34-
# @returns [::IO::Endpoint::Generic]
35-
def endpoint
36-
::IO::Endpoint.unix(ipc_path)
37-
end
38-
39-
# Options to use when creating the container.
40-
def container_options
41-
{restart: true, count: 1, health_check_timeout: 30}
22+
def monitors
23+
[Async::Container::Supervisor::MemoryMonitor.new(interval: 10)]
4224
end
4325
end
4426

lib/falcon/service/server.rb

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ def setup(container)
5858
evaluator = @environment.evaluator
5959

6060
Async do |task|
61+
if @environment.implements?(Async::Container::Supervisor::Supervised)
62+
evaluator.make_supervised_worker(instance).run
63+
end
64+
6165
server = evaluator.make_server(@bound_endpoint)
6266

6367
server.run

0 commit comments

Comments
 (0)