quartz 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 05b5dae726bdb30517440604cef9323e3f603977
4
- data.tar.gz: 0b29eb3c722db7dd97b38807b0801914c6bb7bbd
3
+ metadata.gz: 38e17e14fd92fe48bde386619caf1a6c290b382f
4
+ data.tar.gz: 67579895994930814c09d929af14a4df14e38a42
5
5
  SHA512:
6
- metadata.gz: 46f9a875047aeb19208991da607f1bfd21e2e747a660137aa9c75627e11ac0ced0b31d91faab36d565c19caa2c22fdd958c797e1136af5615e572c043fbc0c69
7
- data.tar.gz: 41b49e461b6859c33b4ab87bb6d8f7ff0ef483cacb83ea7317824b49f8b8c6bdd307535d73fd188db3d6db167d1944013eac6b5c5dad36b99446757ba78a524c
6
+ metadata.gz: 1be3464bd2d6dd945f2f7abc0d4da0551c362fa1d69011a35699daa515b325533f43b3acad5e1a91bd83bb30b8a141fe4daad5d626190fa3bfe13395d694cba9
7
+ data.tar.gz: dea73da76d59574c5b984e612b5ff1b97c8025db45c42edeb05b4560500521e54943704532c8a3abd187a63f27dab9d3a35d58d9b5a9bfe1da08eed0a6f3fe6b
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # quartz
2
2
 
3
- [![Build Status](https://travis-ci.org/DavidHuie/quartz.svg?branch=travis-ci-test)](https://travis-ci.org/DavidHuie/quartz)
3
+ [![Build Status](https://travis-ci.org/DavidHuie/quartz.svg?branch=master)](https://travis-ci.org/DavidHuie/quartz)
4
4
 
5
5
  Quartz enables you to call Go code from within your
6
6
  Ruby code. This is accomplished by running a Go program
@@ -43,7 +43,7 @@ func (t *Adder) Add(args Args, response *Response) error {
43
43
  ## Preparing a Quartz RPC server in Go
44
44
 
45
45
  Instead of integrating Quartz into an existing Go application,
46
- it is recommended to create a new `go run`-able file
46
+ it is recommended to create a new program
47
47
  that explicitly defines the structs that should be available
48
48
  to Ruby.
49
49
 
@@ -77,11 +77,18 @@ Naturally:
77
77
  $ gem install quartz
78
78
  ```
79
79
 
80
- After you've found created a `go run`-able file, create a Go client that
80
+ If you have a `go run`-able file, you can create a Go client that
81
81
  points to that file:
82
82
 
83
83
  ```ruby
84
- client = Quartz::Client.new(file_path: 'spec/test.go')
84
+ client = Quartz::Client.new(file_path: 'my_adder.go')
85
+ ```
86
+
87
+ If you compiled the Go program yourself, you can create a client
88
+ that points to the binary like this:
89
+
90
+ ```ruby
91
+ client = Quartz::Client.new(bin_path: 'my_adder_binary')
85
92
  ```
86
93
 
87
94
  To list exported structs:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/go/quartz/quartz.go CHANGED
@@ -118,8 +118,13 @@ func (q *Quartz) GetMetadata(_ interface{}, value *map[string]*StructMetadata) e
118
118
  }
119
119
 
120
120
  func init() {
121
+ socket_path := os.Getenv("QUARTZ_SOCKET")
122
+ if socket_path == "" {
123
+ socket_path = "/tmp/quartz.socket"
124
+ }
125
+
121
126
  var err error
122
- listener, err = net.Listen("unix", os.Getenv("QUARTZ_SOCKET"))
127
+ listener, err = net.Listen("unix", socket_path)
123
128
  if err != nil {
124
129
  panic(err)
125
130
  }
@@ -131,7 +136,7 @@ func init() {
131
136
 
132
137
  // Cleanup the socket file when the server is killed
133
138
  sigc := make(chan os.Signal)
134
- signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM)
139
+ signal.Notify(sigc, syscall.SIGTERM)
135
140
  go func() {
136
141
  <-sigc
137
142
  err := listener.Close()
data/lib/quartz/client.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  class Quartz::Client
2
2
 
3
3
  def initialize(opts)
4
- @process = Quartz::GoProcess.new(file_path: opts[:file_path])
4
+ @process = Quartz::GoProcess.new(opts)
5
5
  @structs = {}
6
6
  @process.get_metadata.each do |struct_name, metadata|
7
7
  @structs[struct_name.to_sym] = Quartz::GoStruct.new(struct_name, metadata, @process)
@@ -1,18 +1,39 @@
1
1
  class Quartz::GoProcess
2
2
 
3
+ attr_reader :temp_file_path
4
+
5
+ def self.processes
6
+ @processes ||= []
7
+ end
8
+
3
9
  def initialize(opts)
4
- @socket_path = "/tmp/quartz#{rand(10000)}.sock"
10
+ @socket_path = "/tmp/quartz_#{rand(10000)}.sock"
5
11
  ENV['QUARTZ_SOCKET'] = @socket_path
6
12
 
7
13
  if opts[:file_path]
8
- @go_process = Thread.new { `go run #{opts[:file_path]} }` }
14
+ compile_and_run(opts[:file_path])
9
15
  elsif opts[:bin_path]
10
- @go_process = Thread.new { `#{opts[:bin_path]} }` }
16
+ @go_process = IO.popen(opts[:bin_path])
11
17
  else
12
18
  raise 'Missing go binary'
13
19
  end
14
20
 
15
21
  block_until_server_starts
22
+ self.class.processes << self
23
+ end
24
+
25
+ def compile_and_run(path)
26
+ @temp_file_path = "/tmp/quartz_runner_#{rand(10000)}"
27
+
28
+ unless system('go', 'build', '-o', @temp_file_path, path)
29
+ raise 'Go compilation failed'
30
+ end
31
+
32
+ @go_process = IO.popen(@temp_file_path)
33
+ end
34
+
35
+ def pid
36
+ @go_process.pid
16
37
  end
17
38
 
18
39
  def socket
@@ -40,7 +61,13 @@ class Quartz::GoProcess
40
61
  }
41
62
 
42
63
  socket.send(payload.to_json, 0)
43
- read
64
+ response = read
65
+
66
+ if response['error']
67
+ raise "Metadata error: #{read['error']}"
68
+ end
69
+
70
+ response['result']
44
71
  end
45
72
 
46
73
  def call(struct_name, method, args)
@@ -61,7 +88,20 @@ class Quartz::GoProcess
61
88
  MAX_MESSAGE_SIZE = 1_000_000_000 # Bytes
62
89
 
63
90
  def read
64
- JSON(socket.recv(MAX_MESSAGE_SIZE))['result']
91
+ JSON(socket.recv(MAX_MESSAGE_SIZE))
92
+ end
93
+
94
+ def cleanup
95
+ Process.kill('SIGTERM', pid)
96
+ Process.wait(pid)
97
+ File.delete(@temp_file_path) if @temp_file_path
98
+ self.class.processes.delete(self)
99
+ end
100
+
101
+ def self.cleanup
102
+ processes.each { |p| p.cleanup }
65
103
  end
66
104
 
67
105
  end
106
+
107
+ at_exit { Quartz::GoProcess.cleanup }
@@ -30,7 +30,13 @@ class Quartz::GoStruct
30
30
  # TODO: validate type
31
31
  end
32
32
 
33
- @process.call(@struct_name, method_name, args)
33
+ response = @process.call(@struct_name, method_name, args)
34
+
35
+ if response['error']
36
+ raise "Error calling #{method_name}: #{response['error']}"
37
+ end
38
+
39
+ response['result']
34
40
  end
35
41
 
36
42
  end
data/quartz.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: quartz 0.1.0 ruby lib
5
+ # stub: quartz 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "quartz"
9
- s.version = "0.1.0"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["David Huie"]
13
- s.date = "2014-06-16"
13
+ s.date = "2014-06-17"
14
14
  s.description = "A gem for calling #golang code from ruby"
15
15
  s.email = "dahuie@gmail.com"
16
16
  s.extra_rdoc_files = [
@@ -20,7 +20,40 @@ describe Quartz::GoProcess do
20
20
 
21
21
  it 'is able to call a method on a struct' do
22
22
  result = process.call('adder', 'Add', { 'A' => 5, 'B' => 6 })
23
- result.should eq({"X"=>11})
23
+ result.should eq({"id"=>1, "result"=>{"X"=>11}, "error"=>nil})
24
+ end
25
+
26
+ end
27
+
28
+ it 'works with an existing binary file' do
29
+ temp_file = "/tmp/quartz_test_#{rand(10000)}"
30
+ system('go', 'build', '-o', temp_file, 'spec/test.go')
31
+ process = Quartz::GoProcess.new(bin_path: temp_file)
32
+ result = process.call('adder', 'Add', { 'A' => 5, 'B' => 6 })
33
+ result.should eq({"id"=>1, "result"=>{"X"=>11}, "error"=>nil})
34
+ File.delete(temp_file)
35
+ end
36
+
37
+ describe '.cleanup' do
38
+
39
+ context 'files' do
40
+
41
+ it "it deletes temporary files" do
42
+ File.exists?(process.temp_file_path).should be_true
43
+ process.cleanup
44
+ File.exists?(process.temp_file_path).should be_false
45
+ end
46
+
47
+ end
48
+
49
+ context 'processes' do
50
+
51
+ it "it kills child processes" do
52
+ File.exists?(process.temp_file_path).should be_true
53
+ process.cleanup
54
+ File.exists?(process.temp_file_path).should be_false
55
+ end
56
+
24
57
  end
25
58
 
26
59
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quartz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Huie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-16 00:00:00.000000000 Z
11
+ date: 2014-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec