Skip to content

Commit

Permalink
Add Apollo Engine Proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
exAspArk committed Oct 25, 2017
1 parent 3b8ac14 commit ca9b02f
Showing 11 changed files with 271 additions and 83 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
/pkg/
/spec/reports/
/tmp/
/bin/engineproxy*

# rspec failure tracking
.rspec_status
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -2,4 +2,4 @@ sudo: false
language: ruby
rvm:
- 2.3.4
script: bundle exec rspec
script: make download_binaries && bundle exec rspec
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -8,10 +8,14 @@ one of the following labels: `Added`, `Changed`, `Deprecated`,
to manage the versions of this gem so
that you can set version constraints properly.

#### [Unreleased](https://github.com/uniiverse/apollo-tracing-ruby/compare/v1.0.0...HEAD)
#### [Unreleased](https://github.com/uniiverse/apollo-tracing-ruby/compare/v1.1.0...HEAD)

* WIP

#### [v1.1.0](https://github.com/uniiverse/apollo-tracing-ruby/compare/v1.0.0..v1.1.0) – 2017-10-25

* `Added`: Apollo Engine Proxy version [2017.10-408-g497e1410](https://www.apollographql.com/docs/engine/proxy-release-notes.html). ([#2](https://github.com/uniiverse/apollo-tracing-ruby/pull/2))

#### [v1.0.0](https://github.com/uniiverse/apollo-tracing-ruby/compare/v0.1.1...v1.0.0) – 2017-10-17

* `Changed`: the gem name from `graphql-tracing` to `apollo-tracing`.
17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
download_binaries:
curl -O https://registry.npmjs.org/apollo-engine-binary-darwin/-/apollo-engine-binary-darwin-0.2017.10-408-g497e1410.tgz
curl -O https://registry.npmjs.org/apollo-engine-binary-darwin/-/apollo-engine-binary-linux-0.2017.10-408-g497e1410.tgz
curl -O https://registry.npmjs.org/apollo-engine-binary-darwin/-/apollo-engine-binary-windows-0.2017.10-408-g497e1410.tgz
tar -xzf apollo-engine-binary-darwin-0.2017.10-408-g497e1410.tgz
tar -xzf apollo-engine-binary-linux-0.2017.10-408-g497e1410.tgz
tar -xzf apollo-engine-binary-windows-0.2017.10-408-g497e1410.tgz
mv package/engineproxy_darwin_amd64 bin/
mv package/engineproxy_linux_amd64 bin/
mv package/engineproxy_windows_amd64.exe bin/
rm -r package/
rm apollo-engine-binary-darwin-0.2017.10-408-g497e1410.tgz
rm apollo-engine-binary-linux-0.2017.10-408-g497e1410.tgz
rm apollo-engine-binary-windows-0.2017.10-408-g497e1410.tgz

release: download_binaries
bundle exec rake release
111 changes: 103 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,17 @@

Ruby implementation of [GraphQL](https://github.com/rmosolgo/graphql-ruby) trace data in the [Apollo Tracing](https://github.com/apollographql/apollo-tracing) format.


## Contents

* [Installation](#installation)
* [Usage](#usage)
* [Tracing](#tracing)
* [Engine Proxy](#engine-proxy)
* [Development](#development)
* [Contributing](#contributing)
* [License](#license)

## Installation

Add this line to your application's Gemfile:
@@ -49,16 +60,18 @@ Schema = GraphQL::Schema.define do
end

# Execute query
query = "query($user_id: ID!) {
posts(user_id: $user_id) {
id
title
}
}"
query = "
query($user_id: ID!) {
posts(user_id: $user_id) {
id
title
}
}
"
Schema.execute(query, variables: { user_id: 1 })
```

### Setup Tracing
### Tracing

Add 'ApolloTracing' to your schema:

@@ -141,6 +154,89 @@ Now your response should look something like:
}
```

### Engine Proxy

Now you can start using the [Apollo Engine](https://www.apollographql.com/engine/) service.
Here is the general architecture overview of a sidecar mode – Proxy runs next to your application server:

```
----------------- request ----------------- request -----------------
| | -----------> | | -----------> | |
| Client | | Engine Proxy | | Application |
| | <----------- | | <----------- | |
----------------- response ----------------- response -----------------
|
|
GraphQL tracing data |
|
˅
-----------------
| |
| Apollo Engine |
| |
-----------------
```

`ApolloTracing` gem comes with the [Apollo Engine Proxy](https://www.apollographql.com/docs/engine/index.html#engine-proxy) binary written in Go.
To configure the Proxy create a Proxy config file:

```
# config/apollo-engine-proxy.json
{
"apiKey": "service:YOUR_ENGINE_API_KEY",
"logging": { "level": "INFO" },
"origins": [{
"http": { "url": "http://localhost:3000/graphql" }
}],
"frontends": [{
"host": "127.0.0.1", "port": 3001, "endpoint": "/graphql"
}]
}
```

* `apiKey` – get this on your [Apollo Engine](https://engine.apollographql.com/) home page.
* `logging.level` – a log level for the Proxy ("INFO", "DEBUG" or "ERROR").
* `origins` – a list of URLs with your GraphQL endpoints in the Application.
* `frontends` – an address on which the Proxy will be listening.

To run the Proxy as a child process, which will be automatically terminated if the Application proccess stoped, add the following line to the `config.ru` file:

<pre>
# config.ru – this file is used by Rack-based servers to start the application.
require File.expand_path('../config/environment', __FILE__)

<b>ApolloTracing.start_proxy('config/apollo-engine-proxy.json')</b>
run Your::Application
</pre>

For example, if you use [rails](https://github.com/rails/rails) with [puma](https://github.com/puma/puma) application server and run it like:

```
bundle exec puma -w 2 -t 16 -p 3001
```

The proccess tree may look like:

```
---------------
| Puma Master |
| Port 3000 |
---------------
| |
---------- ----------
| | ----------------
˅ -> | Puma Worker1 |
---------------- | -----------------
| Engine Proxy | | ----------------
| Port 3001 | -> | Puma Worker2 |
---------------- ----------------
```

Now you can send requests to the reverse Proxy `http://localhost:3001`.
It'll proxy any (GraphQL and non-GraphQL) requests to the Application `http://localhost:3000`.
If the request matches the endpoints described in `origins`, it'll strip the `tracing` data from the response and will send it to the Apollo Engine service.

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -154,4 +250,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/uniive
## License

The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

11 changes: 8 additions & 3 deletions apollo-tracing.gemspec
Original file line number Diff line number Diff line change
@@ -14,9 +14,14 @@ Gem::Specification.new do |spec|
spec.homepage = "https://github.com/uniiverse/apollo-tracing-ruby"
spec.license = "MIT"

spec.files = `git ls-files -z`.split("\x0").reject do |f|
f.match(%r{^(test|spec|features)/})
end
spec.files =
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^test/}) } +
%w[
bin/engineproxy_darwin_amd64
bin/engineproxy_linux_amd64
bin/engineproxy_windows_amd64.exe
]

spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
1 change: 1 addition & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -4,5 +4,6 @@ IFS=$'\n\t'
set -vx

bundle install
make download_binaries

# Do any other automated setup that you need to do here
37 changes: 37 additions & 0 deletions lib/apollo_tracing.rb
Original file line number Diff line number Diff line change
@@ -4,6 +4,43 @@
require "apollo_tracing/version"

class ApolloTracing
def self.start_proxy(config_filepath = 'config/apollo-engine.json')
config_json = File.read(config_filepath)
binary_path =
if RUBY_PLATFORM.include?('darwin')
File.expand_path('../../bin/engineproxy_darwin_amd64', __FILE__)
elsif /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
File.expand_path('../../bin/engineproxy_windows_amd64.exe', __FILE__)
else
File.expand_path('../../bin/engineproxy_linux_amd64', __FILE__)
end

@@proxy_pid = spawn(
{"ENGINE_CONFIG" => config_json},
"#{binary_path} -config=env -restart=true",
{out: STDOUT, err: STDERR}
)
at_exit { stop_proxy }
Process.detach(@@proxy_pid)
@@proxy_pid
end

def self.stop_proxy
Process.getpgid(@@proxy_pid)
Process.kill('TERM', @@proxy_pid)

3.times do
Process.getpgid(@@proxy_pid)
sleep 1
end

Process.getpgid(@@proxy_pid)
puts "Couldn't cleanly terminate the Apollo Engine Proxy in 3 seconds!"
Process.kill('KILL', @@proxy_pid)
rescue Errno::ESRCH
# process does not exist
end

def use(schema_definition)
schema_definition.instrument(:query, self)
schema_definition.instrument(:field, self)
2 changes: 1 addition & 1 deletion lib/apollo_tracing/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class ApolloTracing
VERSION = "1.0.0"
VERSION = "1.1.0"
end
Loading

0 comments on commit ca9b02f

Please sign in to comment.