populus 0.0.1.pre3 → 0.0.1

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
  SHA1:
3
- metadata.gz: b0b59e4ac86d6d258766507d44cc26045420690e
4
- data.tar.gz: 146bdb3308470befc1145bb9a67d26778568bb17
3
+ metadata.gz: 0af5cd919676d03ad1cf32acd295b5f56274d0c6
4
+ data.tar.gz: 373393234f80be72ec88e5d546e84a51f3aaa080
5
5
  SHA512:
6
- metadata.gz: 0ff3f1f915b797f0bb519bf12ed99d44cf52db9d228dfe97dd8b57445f1fdeed22e9f26c7fc24ac923173a394c867e59a65aa744cd55bcfb8362df80e720b8d3
7
- data.tar.gz: 9abc728c5c1b032cc8a9cc43c478afde83cf16b13c93a3dca74c7a431cc26d81befcded09ee1b1eb1af9a01b90ebea81b06b932c862be363b0b88e39a26a70f0
6
+ metadata.gz: 63e3cd016902a544e7d173c4695218786a10bfd7f5f2cc0830c14a48834dd500635a1f3d341f30fac661ed9b1f43367a5c82cc48a59372726b938699e6c27489
7
+ data.tar.gz: 55f5b7ca913d0896f3d26006d96446a68361ccf40f95ae907971af6e06db8a22ecf8155d21e4acd0306a911722b9e55d742a196441d879cfebd31329f9b1edcc
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Populus
2
2
 
3
- TODO: Write a gem description
3
+ [WIP][Will breaking change] Consul event handlers definition DSL
4
4
 
5
5
  ## Installation
6
6
 
@@ -20,11 +20,31 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- TODO: Write usage instructions here
23
+ ### Usages below are just a draft
24
+
25
+ ```ruby
26
+ Populus.watch 'node' do
27
+ on_receive do |nodes|
28
+ if nodes.count < 10
29
+ logger.warn "nodes are too short!"
30
+ end
31
+ end
32
+ end
33
+ ```
34
+
35
+ ```bash
36
+ consul watch -type node "bundle exec populus accept sample.popl"
37
+ ```
38
+
39
+ ### TODOs
40
+
41
+ * Deployment switching by node name
42
+ * Condition phrase against JSON
43
+ * Local/remote execution by specinfra
24
44
 
25
45
  ## Contributing
26
46
 
27
- 1. Fork it ( https://github.com/[my-github-username]/populus/fork )
47
+ 1. Fork it ( https://github.com/udzura/populus/fork )
28
48
  2. Create your feature branch (`git checkout -b my-new-feature`)
29
49
  3. Commit your changes (`git commit -am 'Add some feature'`)
30
50
  4. Push to the branch (`git push origin my-new-feature`)
data/bin/populus CHANGED
@@ -3,15 +3,19 @@
3
3
 
4
4
  require 'populus'
5
5
 
6
- mode = ARGV[0] # This is for forward compatibility
7
- if mode != 'accept'
8
- puts "Unknown arg: #{mode}"
9
- exit 127
10
- end
11
-
6
+ mode = ARGV[0]
12
7
  setting = ARGV[1]
13
8
 
14
- Populus.eval_setting setting
9
+ case mode
10
+ when 'accept'
11
+ # FIXME: implement one-time runner
12
+ Populus.logger.error "FIXME: implement one-time runner"
13
+ exit 127
14
+ when 'watch'
15
+ Populus::Daemon.run(setting: setting)
16
+ else
17
+ Populus.logger.error "Unknown arg: #{mode}"
18
+ exit 127
19
+ end
15
20
 
16
- data = STDIN.read
17
- Populus::Do.accept data
21
+ exit 0
data/examples/echo.popl CHANGED
@@ -1,7 +1,11 @@
1
1
  # -*- mode: ruby -*-
2
+ require 'base64'
2
3
 
3
- Populus.watch 'node' do
4
- on_receive do |json|
5
- p json
4
+ Populus.watch :event, name: "sample" do
5
+ When {|data| data.any?{|d| d.has_key?('Payload')} }
6
+ Runs do |data|
7
+ event = data.find{|d| d.has_key?('Payload')}
8
+ Populus.logger.info "From populus!!!"
9
+ Populus.logger.info Base64.decode64(event['Payload'])
6
10
  end
7
11
  end
@@ -0,0 +1,44 @@
1
+ module Populus
2
+ class Accepter
3
+ # TODO: validators
4
+ class Base
5
+ attr_accessor :condition, :runner, :metadata
6
+
7
+ def initialize(cond: nil, runs: nil, metadata: {})
8
+ self.condition = cond
9
+ self.runner = runs
10
+ self.metadata = metadata
11
+ end
12
+
13
+ def type?(t)
14
+ current_type = self.class.name.downcase
15
+ .split('::')
16
+ .last
17
+ current_type == t
18
+ end
19
+
20
+ def accept(data)
21
+ if condition[data]
22
+ Populus.logger.debug "Condition judged true: #{data.inspect}"
23
+ runner[data]
24
+ return true
25
+ else
26
+ Populus.logger.debug "Condition judged false: #{data.inspect}"
27
+ return false
28
+ end
29
+ end
30
+ end
31
+
32
+ class Event < Base
33
+ def has_name?(name)
34
+ metadata[:name] == name
35
+ end
36
+
37
+ def create_thread
38
+ _name = metadata[:name]
39
+ Populus.logger.debug "Create thread: consul watch -type event -name #{_name}"
40
+ Populus::WatchThread.consul_watch('-type', 'event', '-name', _name)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require 'populus/watch_thread'
2
+ require 'securerandom'
3
+
4
+ module Populus
5
+ module Daemon
6
+ def self.run(setting: nil)
7
+ raise ArgumentError unless setting
8
+ Populus.eval_setting(setting)
9
+ threads = Populus::Pool.gen_threads
10
+
11
+ trap(:INT) do
12
+ STDERR.puts "Caught SIGINT. Quitting..."
13
+ threads.each(&:kill)
14
+ end
15
+
16
+ threads.each(&:join)
17
+ Populus.logger.warn "Consul process exited. Aborting..."
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ require 'logger'
2
+ require 'colorize'
3
+ module Populus
4
+ class DefaultLoggerFormatter < ::Logger::Formatter
5
+ COLOR_CODE = {
6
+ 'DEBUG' => :black,
7
+ 'INFO' => :green,
8
+ 'WARN' => :yellow,
9
+ 'ERROR' => :red,
10
+ 'FATAL' => :magenta,
11
+ }
12
+
13
+ def call(severity, time, progname, msg)
14
+ s = super
15
+ s[0] = ("%5s" % severity).colorize(:color => COLOR_CODE[severity])
16
+ s
17
+ end
18
+ end
19
+
20
+ logger = ::Logger.new(STDOUT)
21
+ logger.level = ::Logger::DEBUG
22
+ logger.formatter = DefaultLoggerFormatter.new
23
+ DefaultLogger = logger
24
+ end
data/lib/populus/dsl.rb CHANGED
@@ -1,23 +1,44 @@
1
- require 'populus/do'
2
- require 'populus/watch/node'
1
+ require 'populus/pool'
2
+ require 'populus/accepter'
3
3
 
4
4
  module Populus
5
+
6
+ # Populus.watch :event, name: "sample" do
7
+ # When {|data| data.has_key?('Payload') }
8
+ # Runs do |data|
9
+ # Populus.logger.info Base64.decode(data['Payload'])
10
+ # end
11
+ # end
5
12
  module DSL
6
- def watch(arg, &b)
7
- watching = find_watch_obj(arg)
8
- watching.instance_eval(&b)
9
- Do.register_object watching
13
+ class DSLContext
14
+ def initialize(wrap_obj)
15
+ @wrap_obj = wrap_obj
16
+ end
17
+
18
+ def When(&do_foobar)
19
+ @wrap_obj.condition = do_foobar
20
+ end
21
+
22
+ def Runs(&do_foobar)
23
+ @wrap_obj.runner = do_foobar
24
+ end
25
+ end
26
+
27
+ def watch(type, *arg, &b)
28
+ accepter = find_accepter(type.to_s).new(metadata: arg.first)
29
+ DSLContext.new(accepter).instance_eval(&b)
30
+ Pool.register_object accepter
10
31
  end
11
32
 
12
- def find_watch_obj(arg)
13
- const = arg.gsub(/(^.|_.)/) {|c| c.tr('_', '').upcase }
14
- Watch.const_get(const).new
33
+ def find_accepter(type)
34
+ const = type.gsub(/(^.|_.)/) {|c| c.tr('_', '').upcase }
35
+ Accepter.const_get(const)
15
36
  end
16
37
 
17
38
  def eval_setting(path)
18
39
  load path
19
40
  rescue => e
20
- STDERR.puts "Invalid setting format! #{path}", "error is:", e
41
+ STDERR.puts "Invalid setting format! #{path}", "error is:", e.class, e.message, e.backtrace
21
42
  exit 1
22
43
  end
23
44
  end
@@ -0,0 +1,34 @@
1
+ require 'singleton'
2
+ require 'json'
3
+
4
+ module Populus
5
+ class Pool
6
+ include Singleton
7
+
8
+ def objects
9
+ @objects ||= []
10
+ end
11
+
12
+ class << self
13
+ def register_object(o)
14
+ instance.objects << o
15
+ Populus.logger.info "Registered: #{o.inspect}"
16
+ end
17
+
18
+ # TODO: Trying Enumerable#lazy
19
+ def events
20
+ instance.objects.select {|o| o.type?('event') }
21
+ end
22
+
23
+ def find_events_by_name(name)
24
+ events.select{|o| o.has_name?(name) }
25
+ end
26
+
27
+ def gen_threads
28
+ instance.objects.map { |o|
29
+ o.create_thread
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,3 +1,3 @@
1
1
  module Populus
2
- VERSION = "0.0.1.pre3"
2
+ VERSION = "0.0.1"
3
3
  end
@@ -0,0 +1,37 @@
1
+ require 'thread'
2
+ require 'open3'
3
+
4
+ require 'populus/pool'
5
+ require 'json'
6
+
7
+ module Populus
8
+ class WatchThread
9
+ def self.consul_watch(*args)
10
+ wait = Thread.fork do
11
+ begin
12
+ stdin, stdout, stderr = *Open3.popen3(
13
+ Populus.consul_bin, 'watch', *args, '/bin/cat'
14
+ )
15
+ stdin.close
16
+ name = args[args.index('-name') + 1]
17
+ while l = stdout.gets
18
+ Populus.logger.debug "accept JSON: %s" % l
19
+ data = JSON.parse l
20
+
21
+ accepters = Populus::Pool.find_events_by_name(name)
22
+ accepters.each do |accepter|
23
+ begin
24
+ accepter.accept(data)
25
+ rescue => e
26
+ Populus.logger.warn "Error on event: %s, %s. Skip." % [e.class, e.message]
27
+ end
28
+ end
29
+ end
30
+ rescue => e
31
+ Populus.logger.error e
32
+ end
33
+ end
34
+ return wait
35
+ end
36
+ end
37
+ end
data/lib/populus.rb CHANGED
@@ -1,5 +1,18 @@
1
1
  module Populus; end
2
2
 
3
- require "populus/do"
3
+ require "logger"
4
+ require "populus/pool"
4
5
  require "populus/dsl"
6
+ require "populus/daemon"
7
+ require "populus/watch_thread"
8
+ require "populus/default_logger"
5
9
  require "populus/version"
10
+
11
+ module Populus
12
+ class << self
13
+ attr_accessor :consul_bin, :logger
14
+ end
15
+
16
+ self.consul_bin = 'consul' # default to count on $PATH
17
+ self.logger = Populus::DefaultLogger
18
+ end
data/populus.gemspec CHANGED
@@ -14,11 +14,12 @@ Gem::Specification.new do |spec|
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "specinfra"
22
+ spec.add_dependency "colorize"
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.7"
24
25
  spec.add_development_dependency "rake", ">= 10.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: populus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre3
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio, KONDO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-21 00:00:00.000000000 Z
11
+ date: 2015-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: specinfra
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -55,8 +69,7 @@ dependencies:
55
69
  description: Consul event definition DSL
56
70
  email:
57
71
  - udzura@udzura.jp
58
- executables:
59
- - populus
72
+ executables: []
60
73
  extensions: []
61
74
  extra_rdoc_files: []
62
75
  files:
@@ -69,10 +82,13 @@ files:
69
82
  - bin/populus
70
83
  - examples/echo.popl
71
84
  - lib/populus.rb
72
- - lib/populus/do.rb
85
+ - lib/populus/accepter.rb
86
+ - lib/populus/daemon.rb
87
+ - lib/populus/default_logger.rb
73
88
  - lib/populus/dsl.rb
89
+ - lib/populus/pool.rb
74
90
  - lib/populus/version.rb
75
- - lib/populus/watch/node.rb
91
+ - lib/populus/watch_thread.rb
76
92
  - populus.gemspec
77
93
  homepage: https://github.com/udzura/populus
78
94
  licenses:
@@ -89,12 +105,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
105
  version: '0'
90
106
  required_rubygems_version: !ruby/object:Gem::Requirement
91
107
  requirements:
92
- - - ">"
108
+ - - ">="
93
109
  - !ruby/object:Gem::Version
94
- version: 1.3.1
110
+ version: '0'
95
111
  requirements: []
96
112
  rubyforge_project:
97
- rubygems_version: 2.2.2
113
+ rubygems_version: 2.2.3
98
114
  signing_key:
99
115
  specification_version: 4
100
116
  summary: Consul event definition DSL
data/lib/populus/do.rb DELETED
@@ -1,25 +0,0 @@
1
- require 'singleton'
2
- require 'json'
3
-
4
- module Populus
5
- class Do
6
- include Singleton
7
- def objects
8
- @objects ||= []
9
- end
10
-
11
- class << self
12
- def register_object(o)
13
- instance.objects << o
14
- puts "Registered: #{o.inspect}"
15
- end
16
-
17
- def accept(input)
18
- json = JSON.parse(input)
19
- instance.objects.each do |o|
20
- o.accept json
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- module Populus
2
- module Watch
3
- class Node
4
- def initialize
5
- @on_receive_hooks = []
6
- end
7
-
8
- def on_receive(&b)
9
- @on_receive_hooks << b
10
- end
11
-
12
- def accept(json)
13
- @on_receive_hooks.each do |hook|
14
- begin
15
- hook.call(json)
16
- rescue => e
17
- puts e, "Ignore."
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end