Skip to content

Commit f485b82

Browse files
committed
Setup Github Action
1 parent 417e627 commit f485b82

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

.github/workflows/test.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Test
2+
on:
3+
push:
4+
branches: [master]
5+
pull_request:
6+
branches: [master]
7+
workflow_dispatch:
8+
schedule:
9+
- cron: 13 7 * * 6
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
ruby_version:
17+
- 3.3.8
18+
- 3.4.3
19+
experimental: [false]
20+
include:
21+
- ruby_version: head
22+
experimental: true
23+
name: Ruby ${{ matrix.ruby_version }}
24+
continue-on-error: ${{ matrix.experimental }}
25+
steps:
26+
- name: "[Git] Checkout code"
27+
uses: actions/checkout@v4
28+
29+
- uses: crystal-lang/install-crystal@v1
30+
with:
31+
crystal: 1.15.1
32+
33+
- uses: ruby/setup-ruby@v1
34+
with:
35+
ruby-version: ${{ matrix.ruby_version }}
36+
bundler-cache: true
37+
38+
- name: "[Test] Run tests"
39+
run: |
40+
bundle exec crystalruby clean
41+
bundle exec rake test
42+
env:
43+
CRYSTAL_RUBY_SINGLE_THREAD_MODE: true
44+
45+
- name: "[Test] Validate examples"
46+
run: |
47+
for example in examples/**/*.rb; do
48+
echo " > Processing $example..."
49+
bundle exec ruby $example
50+
done

lib/crystalruby/reactor.rb

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ module Reactor
1010
module_function
1111

1212
class SingleThreadViolation < StandardError; end
13+
1314
class StopReactor < StandardError; end
1415

16+
@op_count = 0
1517
@single_thread_mode = false
1618

1719
REACTOR_QUEUE = Queue.new
@@ -44,7 +46,7 @@ class StopReactor < StandardError; end
4446

4547
# We memoize callbacks, once per return type
4648
CALLBACKS_MAP = Hash.new do |h, rt|
47-
h[rt] = FFI::Function.new(:void, [:int, *(rt == :void ? [] : [rt])]) do |tid, ret|
49+
h[rt] = FFI::Function.new(:void, [:int, *((rt == :void) ? [] : [rt])]) do |tid, ret|
4850
THREAD_MAP[tid][:error] = nil
4951
THREAD_MAP[tid][:result] = ret
5052
THREAD_MAP[tid][:cond].signal
@@ -104,12 +106,13 @@ def start!
104106
CrystalRuby.log_debug("CrystalRuby initialized")
105107
while true
106108
handler, *args, lib = REACTOR_QUEUE.pop
109+
puts "\n\n\n======================="
107110
send(handler, *args, lib)
108111
@op_count += 1
109112
invoke_gc_if_due!(lib)
110113
end
111-
rescue StopReactor => e
112-
rescue StandardError => e
114+
rescue StopReactor
115+
rescue => e
113116
CrystalRuby.log_error "Error: #{e}"
114117
CrystalRuby.log_error e.backtrace
115118
end
@@ -123,20 +126,21 @@ def gc_due?
123126
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
124127

125128
# Initialize state variables if not already set.
126-
@last_gc_time ||= now
127-
@last_gc_op_count ||= @op_count
129+
@last_gc_time ||= now
130+
@op_count ||= 0
131+
@last_gc_op_count ||= @op_count
128132
@last_mem_check_time ||= now
129133

130134
# Calculate differences based on ops and time.
131-
ops_since_last_gc = @op_count - @last_gc_op_count
135+
ops_since_last_gc = @op_count - @last_gc_op_count
132136
time_since_last_gc = now - @last_gc_time
133137

134138
# Start with our two “cheap” conditions.
135139
due = (ops_since_last_gc >= GC_OP_THRESHOLD) || (time_since_last_gc >= GC_INTERVAL) || Types::Allocator.gc_bytes_seen > GC_BYTES_SEEN_THRESHOLD
136140

137141
if due
138142
# Update the baseline values after GC is scheduled.
139-
@last_gc_time = now
143+
@last_gc_time = now
140144
# If we just did a memory check, use that value; otherwise, fetch one now.
141145
@last_gc_op_count = @op_count
142146
Types::Allocator.gc_hint_reset!
@@ -173,10 +177,10 @@ def invoke_blocking!(receiver, op_name, *args, tvars, _lib)
173177
tvars[:error] = nil
174178
begin
175179
tvars[:result] = receiver.send(op_name, *args)
176-
rescue StopReactor => e
180+
rescue StopReactor
177181
tvars[:cond].signal
178182
raise
179-
rescue StandardError => e
183+
rescue => e
180184
tvars[:error] = e
181185
end
182186
tvars[:cond].signal
@@ -191,8 +195,8 @@ def schedule_work!(receiver, op_name, *args, return_type, blocking: true, async:
191195
if @single_thread_mode || (Thread.current.object_id == @main_thread_id && op_name != :yield)
192196
unless Thread.current.object_id == @main_thread_id
193197
raise SingleThreadViolation,
194-
"Single thread mode is enabled, cannot run in multi-threaded mode. " \
195-
"Reactor was started from: #{@main_thread_id}, then called from #{Thread.current.object_id}"
198+
"Single thread mode is enabled, cannot run in multi-threaded mode. " \
199+
"Reactor was started from: #{@main_thread_id}, then called from #{Thread.current.object_id}"
196200
end
197201
invoke_gc_if_due!(lib)
198202
return receiver.send(op_name, *args)

0 commit comments

Comments
 (0)