hakuban 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,119 @@
1
+
2
+ module Hakuban
3
+
4
+ module Stream
5
+
6
+ def each(*args,**kwargs,&block)
7
+ StreamEnumerator.new(self,false,false,false,args,kwargs).call_or_return(&block)
8
+ end
9
+
10
+ class KilledOnNext < Exception; end
11
+
12
+ #TODO: meh
13
+ class StreamEnumerator
14
+
15
+ def initialize(stream, without_implicit_drop, async, kill_on_next, args, kwargs)
16
+ @stream, @without_implicit_drop, @async, @kill_on_next, @args, @kwargs = stream, without_implicit_drop, async, kill_on_next, args, kwargs
17
+ end
18
+
19
+ def async(*args,**kwargs,&block)
20
+ StreamEnumerator.new(@stream, @without_implicit_drop, :async, @kill_on_next, @args+args, @kwargs.merge(kwargs)).call_or_return(&block)
21
+ end
22
+
23
+ def thread(*args,**kwargs,&block)
24
+ StreamEnumerator.new(@stream, @without_implicit_drop, :thread, @kill_on_next, @args+args, @kwargs.merge(kwargs)).call_or_return(&block)
25
+ end
26
+
27
+ def without_implicit_drop(*args,**kwargs,&block)
28
+ StreamEnumerator.new(@stream, true, @async, @kill_on_next, @args+args, @kwargs.merge(kwargs)).call_or_return(&block)
29
+ end
30
+
31
+ def kill_on_next(*args,**kwargs,&block)
32
+ StreamEnumerator.new(@stream, @without_implicit_drop, @async, true, @args+args, @kwargs.merge(kwargs)).call_or_return(&block)
33
+ end
34
+
35
+ def call_or_return(&block)
36
+ if block
37
+ Thread.handle_interrupt(Object => :never) {
38
+ begin
39
+ to_kill = nil
40
+ Thread.handle_interrupt(Object => :immediate) {
41
+ while new_item = @stream.next
42
+ case @async
43
+ when false
44
+ sync_call(new_item, block)
45
+ when :async
46
+ if @kill_on_next
47
+ if to_kill
48
+ to_kill.stop
49
+ to_kill.wait
50
+ end
51
+ end
52
+ to_kill = Async(new_item) { |_task, item|
53
+ sync_call(item, block)
54
+ }
55
+ when :thread
56
+ if @kill_on_next
57
+ if to_kill
58
+ to_kill.raise KilledOnNext.new
59
+ to_kill.value
60
+ end
61
+ end
62
+ to_kill = Thread.new(new_item) { |item|
63
+ sync_call(item, block)
64
+ }
65
+ end
66
+ end
67
+
68
+ case @async
69
+ when false
70
+ when :async
71
+ if @kill_on_next
72
+ if to_kill
73
+ to_kill.stop
74
+ to_kill.wait
75
+ end
76
+ end
77
+ when :thread
78
+ if @kill_on_next
79
+ if to_kill
80
+ to_kill.raise KilledOnNext.new
81
+ to_kill.value
82
+ end
83
+ end
84
+ end
85
+ }
86
+ ensure
87
+ #TODO: should we kill still-running sub-tasks here, or await? or maybe kill on exception, and await otherwise?
88
+ end
89
+ }
90
+ else
91
+ self
92
+ end
93
+ end
94
+
95
+ private def sync_call(item, block)
96
+ if @without_implicit_drop
97
+ begin
98
+ block.call(item, *@args, **@kwargs)
99
+ rescue KilledOnNext
100
+ end
101
+ else
102
+ Thread.handle_interrupt(Object => :never) {
103
+ begin
104
+ Thread.handle_interrupt(Object => :immediate) {
105
+ block.call(item, *@args, **@kwargs)
106
+ }
107
+ rescue KilledOnNext
108
+ ensure
109
+ item.drop
110
+ end
111
+ }
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+ end
118
+
119
+ end
@@ -0,0 +1,32 @@
1
+ require 'hakuban/ffi-object.rb'
2
+
3
+ module Hakuban
4
+
5
+ class Tokio
6
+
7
+ @@pointer = nil
8
+
9
+ def Tokio.init(workers_count=0)
10
+ Hakuban::hakuban_initialize
11
+ @@pointer ||= FFI::hakuban_tokio_init_multi_thread(0)
12
+ end
13
+
14
+ def Tokio.pointer
15
+ Tokio.init if not @@pointer
16
+ @@pointer
17
+ end
18
+
19
+ end
20
+
21
+
22
+ class WebsocketConnector < FFIObject
23
+
24
+ def initialize(local_exchange, url, &block)
25
+ pointer = local_exchange.with_pointer { |local_exchange_pointer| FFI::hakuban_tokio_websocket_connector_new(Tokio.pointer, local_exchange_pointer, url) }.unwrap
26
+ initialize_pointer(pointer, :hakuban_tokio_websocket_connector_drop, nil)
27
+ self.do_and_drop_or_return(&block)
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hakuban
4
- VERSION = "0.6.5"
4
+ VERSION = "0.7.0"
5
5
  end
data/lib/hakuban.rb CHANGED
@@ -1,10 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "hakuban/version"
4
- require_relative "hakuban/hakuban"
5
- require_relative "hakuban/engine"
6
- #require_relative "hakuban/async"
7
- #require_relative "hakuban/thread"
8
-
9
3
  module Hakuban
4
+
5
+ def self.hakuban_initialize
6
+ require_relative 'hakuban/ffi.rb'
7
+ end
8
+
10
9
  end
10
+
11
+
12
+ require_relative 'hakuban/contract.rb'
13
+ require_relative 'hakuban/descriptor.rb'
14
+ require_relative "hakuban/engine"
15
+ require_relative 'hakuban/exchange.rb'
16
+ require_relative 'hakuban/ffi-object.rb'
17
+ require_relative 'hakuban/logger.rb'
18
+ require_relative 'hakuban/object_state_sink.rb'
19
+ require_relative 'hakuban/object_state_stream.rb'
20
+ require_relative 'hakuban/object_state.rb'
21
+ require_relative 'hakuban/tokio-websocket-connector.rb'
22
+ require_relative "hakuban/version"
23
+
24
+
25
+ #TODO: error classes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hakuban
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yunta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-26 00:00:00.000000000 Z
11
+ date: 2023-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.21'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.21'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: ffi
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -71,23 +85,28 @@ email:
71
85
  - maciej.blomberg@mikoton.com
72
86
  executables:
73
87
  - hakuban-observer
74
- - hakuban-thread-engine
88
+ - hakuban-engine
75
89
  extensions: []
76
90
  extra_rdoc_files: []
77
91
  files:
78
92
  - MIT-LICENSE
79
93
  - README.md
80
94
  - Rakefile
95
+ - bin/hakuban-engine
81
96
  - bin/hakuban-observer
82
- - bin/hakuban-thread-engine
83
97
  - lib/hakuban.rb
84
- - lib/hakuban/async.rb
98
+ - lib/hakuban/contract.rb
99
+ - lib/hakuban/descriptor.rb
85
100
  - lib/hakuban/engine.rb
86
- - lib/hakuban/event-queue.rb
101
+ - lib/hakuban/exchange.rb
102
+ - lib/hakuban/ffi-object.rb
87
103
  - lib/hakuban/ffi.rb
88
- - lib/hakuban/hakuban.rb
89
- - lib/hakuban/manager.rb
90
- - lib/hakuban/thread.rb
104
+ - lib/hakuban/logger.rb
105
+ - lib/hakuban/object_state.rb
106
+ - lib/hakuban/object_state_sink.rb
107
+ - lib/hakuban/object_state_stream.rb
108
+ - lib/hakuban/stream.rb
109
+ - lib/hakuban/tokio-websocket-connector.rb
91
110
  - lib/hakuban/version.rb
92
111
  homepage: https://gitlab.com/yunta/hakuban-ruby
93
112
  licenses:
@@ -108,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
127
  - !ruby/object:Gem::Version
109
128
  version: '0'
110
129
  requirements: []
111
- rubygems_version: 3.2.22
130
+ rubygems_version: 3.3.26
112
131
  signing_key:
113
132
  specification_version: 4
114
133
  summary: Ruby binding for Hakuban library
data/lib/hakuban/async.rb DELETED
@@ -1,38 +0,0 @@
1
- require 'hakuban'
2
- require 'hakuban/manager'
3
- require 'async'
4
-
5
- module Hakuban
6
-
7
- class AsyncObjectManager < ObjectManager
8
-
9
- def async_run
10
- Async { yield }
11
- end
12
-
13
- def async_join(task)
14
- task.wait
15
- end
16
-
17
- def async_stop(task)
18
- task.stop
19
- end
20
-
21
- def async_filter_out_stop_exception
22
- yield
23
- rescue Async::Stop
24
- nil
25
- end
26
-
27
- end
28
-
29
-
30
- class ObjectManagerBuilder
31
-
32
- def with_async(&block)
33
- build(AsyncObjectManager, block)
34
- end
35
-
36
- end
37
-
38
- end
@@ -1,75 +0,0 @@
1
- #TODO: rebuild to handle event squashing on rust side
2
-
3
- require 'ostruct'
4
-
5
-
6
- module Hakuban
7
-
8
- class Event < OpenStruct; end
9
-
10
- class ObjectDescriptorCallbackEventQueue
11
-
12
- def initialize(pointer)
13
- @events_pointer = ::FFI::AutoPointer.new(pointer, proc { |ptr| FFI.hakuban_object_descriptor_events_return(ptr) })
14
- end
15
-
16
-
17
- # WARNING: this callback may be run from a separate, non-ruby, thread
18
- def callback_register(&callback)
19
- ffi_callback = proc { |_userdata, ffi_descriptor, ffi_action|
20
- action = Hakuban::action_int_to_symbol(ffi_action)
21
- descriptor = ObjectDescriptor.from_ffi(ffi_descriptor)
22
- callback.call(descriptor, action)
23
- }
24
- @callback_pointer = ::FFI::AutoPointer.new(
25
- FFI::hakuban_object_descriptor_events_callback_register(@events_pointer, ffi_callback, ::FFI::Pointer::NULL),
26
- proc { |ptr| FFI::hakuban_object_descriptor_events_callback_unregister(ptr) }
27
- )
28
- end
29
-
30
-
31
- def callback_unregister
32
- @callback_pointer.free
33
- @callback_pointer = nil
34
- end
35
-
36
-
37
- def drop
38
- @events_pointer.free
39
- @events_pointer = nil
40
- end
41
-
42
- end
43
-
44
-
45
- class ObjectDescriptorEventQueue
46
-
47
- def initialize(contract)
48
- @contract = contract
49
- @queue = Queue.new
50
- @ffi_callback = proc { |descriptor, action|
51
- @queue << Hakuban::Event.new(action: action, descriptor: descriptor)
52
- }
53
- @ffi_events = @contract.new_callback_event_queue
54
- @ffi_events.callback_register(&@ffi_callback)
55
- end
56
-
57
-
58
- #def push(event)
59
- # @queue << event
60
- #end
61
-
62
-
63
- def next_event; next_change; end
64
- def next_change
65
- @queue.pop
66
- end
67
-
68
-
69
- def close
70
- @queue.close
71
- end
72
-
73
- end
74
-
75
- end