SMService 0.1.4 → 0.1.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ba77f89b36377c88a36275cae2ee1cb0fe7933070fe29ee26dc52afcd5d3be14
4
- data.tar.gz: cf59fc3d4f92594b23817a59c4e5623d3e2ba75898894fd7f8aa52402d0fc22a
3
+ metadata.gz: b23b4edc0d637c75e9dbdb47cfcbb141e541d0d74411188613e32d7765005559
4
+ data.tar.gz: c59f2fefb1f552fa7cf43cdd225aa61a00478464468de80d03a17f3a72a4b146
5
5
  SHA512:
6
- metadata.gz: 9c57d922c113e68c45b4dc068e771795c4e1782b8701b1492513b55b662ac51eb73871c35cb90b27aeb911337b968d29877527894427007fdf23b6e67f76f574
7
- data.tar.gz: 0b8dc1990f4e49fb3937d7da8ab818bc71f15d9e945b625617593d39bef173398d3460c88b45928914962e3f9da02a3cb9473039a53d3352547ee0914607b838
6
+ metadata.gz: f2dd0714308ff1120b302e376f6cd963b85aea0c129ff98a5d669866ac7ebb281a1390d7c89d137504b6591b3589ba14439900d6f9e7002b27085e50f45eca48
7
+ data.tar.gz: dbbe8b2b31c9a843ec235d679ecaddcaf0f91093747e1af8addec9f62574674ac18335b64d19492080146082da9bf1ddc9bebf61bac0ce7b5c625d4a8e10c813
data/Dockerfile CHANGED
@@ -20,8 +20,9 @@ RUN apk update \
20
20
  pcre \
21
21
  zlib \
22
22
  tzdata \
23
- mc \
23
+ tmux \
24
24
  vim \
25
+ mc \
25
26
  \
26
27
  && cp -R /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime \
27
28
  && echo 'Europe/Amsterdam' > /etc/timezone \
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- SMService (0.1.3)
4
+ SMService (0.1.5)
5
5
  ffi-rzmq (~> 2.0)
6
6
  logger (~> 1.2)
7
7
  msgpack (~> 1.1)
@@ -9,6 +9,7 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
+ coderay (1.1.2)
12
13
  diff-lcs (1.3)
13
14
  ffi (1.9.18)
14
15
  ffi-rzmq (2.0.5)
@@ -16,7 +17,11 @@ GEM
16
17
  ffi-rzmq-core (1.0.6)
17
18
  ffi
18
19
  logger (1.2.8)
20
+ method_source (0.9.0)
19
21
  msgpack (1.1.0)
22
+ pry (0.11.3)
23
+ coderay (~> 1.1.0)
24
+ method_source (~> 0.9.0)
20
25
  rake (10.5.0)
21
26
  rspec (3.7.0)
22
27
  rspec-core (~> 3.7.0)
@@ -38,6 +43,7 @@ PLATFORMS
38
43
  DEPENDENCIES
39
44
  SMService!
40
45
  bundler (~> 1.16)
46
+ pry (~> 0.11)
41
47
  rake (~> 10.0)
42
48
  rspec (~> 3.0)
43
49
 
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
36
36
 
37
37
 
38
38
  s.add_development_dependency "bundler", "~> 1.16"
39
+ s.add_development_dependency "pry", "~> 0.11"
39
40
  s.add_development_dependency "rake", "~> 10.0"
40
41
  s.add_development_dependency "rspec", "~> 3.0"
41
42
  end
@@ -1,16 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'rubygems'
4
+ require 'pry'
3
5
  require 'bundler'
4
6
  Bundler.setup
5
7
  Bundler.require
6
8
  require 'smservice'
9
+ require_relative '../examples/dummy'
7
10
 
8
- # You can add fixtures and/or initialization code here to make experimenting
9
- # with your gem easier. You can also use a different console, if you like.
11
+ class SMService::Test
12
+ include SMService
10
13
 
11
- # (If you use this, don't forget to add pry to your Gemfile!)
12
- # require "pry"
13
- # Pry.start
14
+ def initialize
15
+ super name: 'test_ruby', actions: 'test'
16
+ end
14
17
 
15
- require "irb"
16
- IRB.start(__FILE__)
18
+ def action_test(headers, message)
19
+ LOGGER.info "#{self.class} - Processing action 'test'. Headers: #{headers.inspect}, message: #{message.inspect}"
20
+ end
21
+ end
22
+
23
+ dummy = SMService::Dummy.new
24
+ dummy.start!
25
+
26
+ test = SMService::Test.new
27
+ test.start!
28
+
29
+ # dummy.execute(action: 'test', message: {my_request: 'ping', my_data: 'add whatever data needed'})
30
+ binding.pry
@@ -0,0 +1,15 @@
1
+ version: '3'
2
+
3
+ networks:
4
+ middleware:
5
+ external:
6
+ name: middleware_default
7
+
8
+ services:
9
+ rubygems:
10
+ build: .
11
+ container_name: rubygems
12
+ volumes:
13
+ - ./:/app
14
+ networks:
15
+ - middleware
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+
3
+ docker build --pull -t rubygems . && \
4
+ docker run -ti --rm --name=rubygems -v ${PWD}:/app rubygems sh
@@ -0,0 +1,11 @@
1
+ class SMService::Dummy
2
+ include SMService
3
+
4
+ def initialize
5
+ super name: 'dummy_ruby', actions: 'someaction'
6
+ end
7
+
8
+ def action_someaction(headers, message)
9
+ LOGGER.info("Processing action 'someaction'. Headers: #{headers.inspect}, message: #{message.inspect}")
10
+ end
11
+ end
@@ -5,19 +5,42 @@ require 'ffi-rzmq'
5
5
  require 'smservice/version'
6
6
 
7
7
  module SMService
8
+ Thread.abort_on_exception = true
9
+
8
10
  LOGGER = Logger.new(STDERR)
9
11
 
10
12
  ENDPOINT_OUT = 'tcp://proxy:6660'
11
13
  ENDPOINT_IN = 'tcp://proxy:6661'
12
14
 
13
- REGISTER_WAIT_TIME = 'infinite'
15
+ REGISTER_WAIT_TIME = 'infinite'
16
+ REGISTER_RETRY = 10
14
17
  KEEPALIVE_WAIT_TIME = 30
15
18
 
16
19
  attr_accessor :socket_in, :socket_out
17
20
  attr_reader :service_name
18
21
 
19
- def initialize(name:)
22
+ # When registering node, following parameters is mandatory:
23
+ #
24
+ # name: name of service/node with its id;
25
+ # actions: list of actions, should be in lowercase and compatible to naming standard for ruby methods
26
+ # actions could be presented as array or as string if service registering only single action
27
+ #
28
+ # Example:
29
+ # SMService::SomeService.new(name: 'dummy-ruby', actions: %w(a b c ping pong))
30
+ #
31
+ # Following actions should be defined as methods for new service, i.e.
32
+ #
33
+ # def action_ping(headers, message)
34
+ # LOGGER.info "#{self.class} - Processing action: PING with headers: #{headers.inspect} and message: #{message.inspect}"
35
+ # # ... business logic here
36
+ # end
37
+ #
38
+ # Prohibited names for actions is register and update, those are reserved to let service communicate with SM.
39
+ # Check SMService::Dummy source code (in examples folder) for detais
40
+ #
41
+ def initialize(name:, actions: [])
20
42
  @service_name = name
43
+ @actions = [%w(ping), actions].flatten.sort.uniq
21
44
 
22
45
  context = ZMQ::Context.new
23
46
  @socket_in = context.socket ZMQ::DEALER
@@ -30,21 +53,41 @@ module SMService
30
53
  @socket_out.connect ENDPOINT_OUT
31
54
  end
32
55
 
33
- def register!(wait_time: REGISTER_WAIT_TIME)
56
+ # starting infinite loop in order to process service logic.
57
+ # start! or service_poller methods could be modified implementing different services, i.e. to run as threaded metod
58
+ def start!
59
+ register
60
+ keep_alive!
61
+ poller!
62
+ end
63
+
64
+ def poller!
65
+ Thread.start do
66
+ poller
67
+ end
68
+ end
69
+
70
+ def poller
71
+ loop do
72
+ pull
73
+ end
74
+ end
75
+
76
+ def register(wait_time: REGISTER_WAIT_TIME)
34
77
  if wait_time.to_f <= 0
35
78
  loop do
36
- register!
79
+ register_service
37
80
  break if registered?
38
81
  # not registered, retrying in 10 seconds
39
- sleep 10
82
+ sleep REGISTER_RETRY
40
83
  end
41
84
  else
42
85
  Timeout::timeout(wait_time) do
43
86
  loop do
44
- register!
87
+ register_service
45
88
  break if registered?
46
89
  # not registered, retrying in 10 seconds
47
- sleep 10
90
+ sleep REGISTER_RETRY
48
91
  end
49
92
  end
50
93
  end
@@ -52,11 +95,11 @@ module SMService
52
95
 
53
96
  def keep_alive!(wait_time: KEEPALIVE_WAIT_TIME)
54
97
  Thread.start do
55
- LOGGER.info "Starting registration update loop with periodic interval #{wait_time} sec"
98
+ LOGGER.info "#{self.class} - Starting registration update loop with periodic interval #{wait_time} sec"
56
99
  loop do
57
100
  break unless registered?
58
101
  sleep wait_time
59
- service_manager('UPDATE', [])
102
+ request(action: 'UPDATE')
60
103
  end
61
104
  LOGGER.info 'Registration update loop terminated'
62
105
  end
@@ -66,55 +109,57 @@ module SMService
66
109
  @registered
67
110
  end
68
111
 
69
- def register!
70
- service_manager('REGISTER', services: [service_name])
71
- pull_action
72
- end
73
-
74
- def service_poller
75
- loop do
76
- pull_action
77
- end
112
+ def action_register(headers, message)
113
+ if headers['action'] == 'REGISTER' && message['result'] == 'OK'
114
+ @registered = true
115
+ LOGGER.info "#{self.class} - Action: REGISTER (successful), headers: #{headers.inspect}, message: #{message.inspect}"
116
+ else
117
+ LOGGER.info "#{self.class} - Action: REGISTER (failure), headers: #{headers.inspect}, message: #{message.inspect}"
118
+ end
78
119
  end
79
120
 
80
- def start!
81
- register!
82
- keep_alive!
83
- service_poller
121
+ def action_ping(headers, message)
122
+ LOGGER.info "#{self.class} - Processing action 'ping'. Headers: #{headers.inspect}, message: #{message.inspect}"
84
123
  end
85
124
 
86
125
  def action_update(headers, message)
87
- LOGGER.info("Action: UPDATE (successful)")
126
+ LOGGER.info "#{self.class} - Processing action 'update'. Headers: #{headers.inspect}, message: #{message.inspect}"
88
127
  end
89
128
 
90
- def action_register(headers, message)
91
- if headers['action'] == 'REGISTER' && message['result'] == 'OK'
92
- @registered = true
93
- LOGGER.info "Action: REGISTER (successful), headers: #{headers.inspect}, message: #{message.inspect}"
94
- else
95
- LOGGER.info "Action: REGISTER (failure), headers: #{headers.inspect}, message: #{message.inspect}"
96
- end
129
+ # Requesting another service, registered at SM to execute given action, example:
130
+ # execute(action: 'create_customer_portal', message: {my_request: 'should create a customer', my_data: 'add whatever data needed'})
131
+ #
132
+ def execute(action:, message: nil)
133
+ LOGGER.info "#{self.class} - SM execute request. Action: #{action.inspect}, message: #{message.inspect}"
134
+ action = {service: action, reply_to: @service_name}.to_msgpack
135
+ message = message.to_msgpack
136
+ @socket_out.send_strings [action, message]
97
137
  end
98
138
 
99
139
  private
100
140
 
141
+ def register_service
142
+ LOGGER.info "#{self.class} - Registering service #{service_name}"
143
+ request(action: 'REGISTER', message: {services: @actions})
144
+ pull
145
+ end
146
+
101
147
  # Sending request to the Service Manager
102
- #
103
- def service_manager(action, message)
104
- LOGGER.info "SM request. Action: #{action.inspect}, message: #{message.inspect}"
148
+ def request(action:, message: nil)
149
+ LOGGER.info "#{self.class} - SM request. Action: #{action.inspect}, message: #{message.inspect}"
105
150
  action = {action: action}.to_msgpack
106
151
  message = message.to_msgpack
107
152
  @socket_in.send_strings [action, message]
108
153
  end
109
154
 
110
- def pull_action
155
+ def pull
111
156
  @socket_in.recv_strings( response = [] )
112
157
 
113
158
  headers, message = response
114
159
  headers = MessagePack.unpack(headers)
115
160
  message = MessagePack.unpack(message)
116
161
 
117
- LOGGER.info "SM response received by pull_action. Headers: #{headers.inspect}, message: #{message.inspect}"
162
+ LOGGER.info "#{self.class} - SM response received by pull. Headers: #{headers.inspect}, message: #{message.inspect}"
118
163
 
119
164
  # Validates is action_name exists as class method and calling it.
120
165
  # In case, if Service Manager return headers['action'] == 'METHOD_NAME',
@@ -128,17 +173,11 @@ private
128
173
  # - action_register, that confirms registration of node with Service Manager, and
129
174
  # - action_update, that confirms successfule registration update, we need it to support keep-alive
130
175
  #
131
- action_name = "action_#{headers['action'].downcase}".to_sym
176
+ action_name = "action_#{(headers['action'] || headers['service']).downcase}".to_sym
132
177
  if respond_to? action_name.to_sym
133
178
  send(action_name, headers, message)
179
+ else
180
+ LOGGER.error "#{self.class} - Method #{action_name} does not exist in class instance for action name #{headers['action']}"
134
181
  end
135
182
  end
136
183
  end
137
-
138
- class SMService::Dummy
139
- include SMService
140
-
141
- def initialize
142
- super name: 'dummy-ruby'
143
- end
144
- end
@@ -1,3 +1,3 @@
1
1
  module SMService
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: SMService
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrius Kairiukstis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-17 00:00:00.000000000 Z
11
+ date: 2017-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.16'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.11'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.11'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rake
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -112,11 +126,14 @@ files:
112
126
  - LICENSE.txt
113
127
  - README.md
114
128
  - Rakefile
129
+ - SMService.gemspec
115
130
  - bin/console
116
131
  - bin/setup
132
+ - docker-compose.yml
133
+ - docker.sh
134
+ - examples/dummy.rb
117
135
  - lib/smservice.rb
118
136
  - lib/smservice/version.rb
119
- - smservice.gemspec
120
137
  homepage: https://github.com/andrius/smservice
121
138
  licenses:
122
139
  - MIT