hakuban 0.6.5 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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