Skip to content

Commit

Permalink
Add AnyCable-Go plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Oct 25, 2021
1 parent 47a11d1 commit 50d75b2
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 10 deletions.
10 changes: 8 additions & 2 deletions kuby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,23 @@
add "RAILS_LOG_LEVEL", "debug"
add "DATABASE_URL", app_creds[:database_url]
add "REDIS_URL", app_creds[:redis_url]
add "ACTION_CABLE_ADAPTER", "redis"
add "ACTION_CABLE_ADAPTER", "any_cable"
add "PROMETHEUS_EXPORTER_PORT", METRICS_PORT.to_s
end
end
end

add_plugin :anycable do
add_plugin :anycable_rpc do
metrics_port METRICS_PORT
replicas 2
end

add_plugin :anycable_go do
metrics_port METRICS_PORT
replicas 2
redis_url app_creds[:redis_url]
end

provider :digitalocean do
access_token app_creds[:do_token]
cluster_id app_creds[:do_cluster_id]
Expand Down
6 changes: 4 additions & 2 deletions lib/kuby/anycable.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

require "kuby"
require "kuby/anycable/plugin"
require "kuby/anycable/rpc_plugin"
require "kuby/anycable/go_plugin"

Kuby.register_plugin(:anycable, Kuby::AnyCable::Plugin)
Kuby.register_plugin(:anycable_rpc, Kuby::AnyCable::RPCPlugin)
Kuby.register_plugin(:anycable_go, Kuby::AnyCable::GoPlugin)
268 changes: 268 additions & 0 deletions lib/kuby/anycable/go_plugin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
# frozen_string_literal: true

module Kuby
module AnyCable
class GoPlugin < ::Kuby::Plugin
extend ::KubeDSL::ValueFields

ROLE = "ws"

value_fields :replicas
value_fields :redis_url
value_fields :metrics_port
value_fields :rpc_host
value_fields :ws_path
value_fields :image
value_fields :hostname

DEFAULT_IMAGE = "anycable/anycable-go:1.1"

attr_reader :port

def after_initialize
@replicas = 1
@metrics_port = nil
@rpc_host = nil
@redis_url = nil
@ws_path = "/cable"
@port = 8081
@hostname = nil
@image = DEFAULT_IMAGE
end

def after_configuration
if rpc_spec && rpc_host.nil?
config_map.data.add("ANYCABLE_RPC_HOST", "dns:///#{rpc_spec.service.metadata.name}:50051")
end

if rails_spec
@hostname ||= rails_spec.hostname
configure_ingress(rails_spec.ingress, hostname)
end
end

def configure(&block)
instance_eval(&block) if block
end

def resources
@resources ||= [
service_account,
service,
config_map,
deployment
]
end

def configure_ingress(ingress, hostname)
spec = self

ingress.spec.rule do
host hostname

http do
path do
path spec.ws_path

backend do
service_name spec.service.metadata.name
service_port spec.service.spec.ports.first.port
end
end
end
end
end

def service_account(&block)
context = self

@service_account ||= KubeDSL.service_account do
metadata do
name "#{context.selector_app}-#{ROLE}-sa"
namespace context.namespace.metadata.name

labels do
add :app, context.selector_app
add :role, ROLE
end
end
end

@service_account.instance_eval(&block) if block
@service_account
end

def service(&block)
spec = self

@service ||= KubeDSL.service do
metadata do
name "#{spec.selector_app}-#{ROLE}-svc"
namespace spec.namespace.metadata.name

labels do
add :app, spec.selector_app
add :role, ROLE
end
end

spec do
type "ClusterIP"

selector do
add :app, spec.selector_app
add :role, ROLE
end

port do
name "http"
port spec.port
protocol "TCP"
target_port "http"
end

if spec.metrics_port
port do
name "metrics"
port spec.metrics_port
protocol "TCP"
target_port "metrics"
end
end
end
end

@service.instance_eval(&block) if block
@service
end

def deployment(&block)
context = self

@deployment ||= KubeDSL.deployment do
metadata do
name "#{context.selector_app}-#{ROLE}"
namespace context.namespace.metadata.name

labels do
add :app, context.selector_app
add :role, ROLE
end
end

spec do
replicas context.replicas

selector do
match_labels do
add :app, context.selector_app
add :role, ROLE
end
end

strategy do
type "RollingUpdate"

rolling_update do
max_surge "25%"
max_unavailable 0
end
end

template do
metadata do
labels do
add :app, context.selector_app
add :role, ROLE
end
end

spec do
container(:ws) do
name "#{context.selector_app}-#{ROLE}"
image context.image
image_pull_policy "IfNotPresent"

port do
container_port context.port
name "http"
protocol "TCP"
end

if context.metrics_port
port do
container_port context.metrics_port
name "metrics"
protocol "TCP"
end
end

env_from do
config_map_ref do
name context.config_map.metadata.name
end
end
end

image_pull_secret do
name context.kubernetes.registry_secret.metadata.name
end

restart_policy "Always"
service_account_name context.service_account.metadata.name
end
end
end
end

@deployment.instance_eval(&block) if block
@deployment
end

def config_map(&block)
spec = self

@config_map ||= KubeDSL.config_map do
metadata do
name "#{spec.selector_app}-#{ROLE}-config"
namespace spec.namespace.metadata.name
end

data do
if spec.rpc_host
add "ANYCABLE_RPC_HOST", spec.rpc_host
end
add "ANYCABLE_REDIS_URL", spec.redis_url
add "ANYCABLE_HOST", "0.0.0.0"
add "ANYCABLE_PORT", spec.port.to_s
if spec.metrics_port
add "ANYCABLE_METRICS_PORT", spec.metrics_port.to_s
add "ANYCABLE_METRICS_HTTP", "/metrics"
end
end
end

@config_map.instance_eval(&block) if block
@config_map
end

alias_method :env, :config_map

delegate :kubernetes, to: :environment

delegate :docker, to: :environment

delegate :selector_app, to: :kubernetes

delegate :namespace, to: :kubernetes

def rpc_spec
@rpc_spec ||= kubernetes.plugin(:anycable_rpc)
end

def rails_spec
@rails_spec ||= kubernetes.plugin(:rails_app)
end
end
end
end
12 changes: 6 additions & 6 deletions lib/kuby/anycable/plugin.rb → lib/kuby/anycable/rpc_plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Kuby
module AnyCable
class Plugin < ::Kuby::Plugin
class RPCPlugin < ::Kuby::Plugin
extend ::KubeDSL::ValueFields

ROLE = "rpc"
Expand All @@ -21,10 +21,10 @@ def after_initialize
end

def after_configuration
return unless rails_app
return unless rails_spec

deployment.spec.template.spec.container(:rpc).merge!(
rails_app.deployment.spec.template.spec.container(:web), fields: [:env_from]
rails_spec.deployment.spec.template.spec.container(:web), fields: [:env_from]
)
end

Expand Down Expand Up @@ -216,7 +216,7 @@ def config_map(&block)
data do
add "ANYCABLE_RPC_HOST", "0.0.0.0:50051"
if spec.redis_url
add "ANYCABLE_REDIS_URL", "0.0.0.0:50051"
add "ANYCABLE_REDIS_URL", spec.redis_url
end
add "ANYCABLE_RPC_SERVER_ARGS__MAX_CONNECTION_AGE_MS", spec.max_connection_age.to_s

Expand All @@ -240,8 +240,8 @@ def config_map(&block)

delegate :namespace, to: :kubernetes

def rails_app
kubernetes.plugin(:rails_app)
def rails_spec
@rails_spec ||= kubernetes.plugin(:rails_app)
end
end
end
Expand Down

0 comments on commit 50d75b2

Please sign in to comment.