Class: Servus::Events::Invocation

Inherits:
Object
  • Object
show all
Defined in:
lib/servus/events/invocation.rb

Overview

A normalized, executable representation of "call this service with these params."

Routers return arrays of Invocation objects. The Bus collects them, deduplicates by #key (first wins), and calls #execute on each.

An Invocation separates identity (service + params) from scheduling (queue, priority, delay). The #key is derived only from the identity — two invocations that call the same service with the same params are considered duplicates regardless of their options.

Invocations are always enqueued, never run inline. A reaction that ran synchronously would put its latency and its failures back into the emitting service, which is what events exist to avoid.

Examples:

Invocation.new(
  service: Notifications::Send::Service,
  params:  { user_id: "abc-123" },
  options: { queue: :mailers, priority: 5 }
)

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(service:, params:, options: {}) ⇒ Invocation

Returns a new instance of Invocation.

Parameters:

  • service (Class)

    the service class

  • params (Hash)

    keyword arguments for the service

  • options (Hash) (defaults to: {})

    scheduling options



46
47
48
49
50
# File 'lib/servus/events/invocation.rb', line 46

def initialize(service:, params:, options: {})
  @service = service
  @params  = params
  @options = options
end

Instance Attribute Details

#optionsHash (readonly)

Returns scheduling options — queue, wait, wait_until, priority, job_options.

Returns:

  • (Hash)

    scheduling options — queue, wait, wait_until, priority, job_options



41
42
43
# File 'lib/servus/events/invocation.rb', line 41

def options
  @options
end

#paramsHash (readonly)

Returns keyword arguments passed to the service.

Returns:

  • (Hash)

    keyword arguments passed to the service



37
38
39
# File 'lib/servus/events/invocation.rb', line 37

def params
  @params
end

#serviceClass (readonly)

Returns the service class to enqueue (must respond to .call_async).

Returns:

  • (Class)

    the service class to enqueue (must respond to .call_async)



34
35
36
# File 'lib/servus/events/invocation.rb', line 34

def service
  @service
end

Instance Method Details

#enqueuevoid

This method returns an undefined value.

Enqueues the invocation via ActiveJob.

Scheduling options (queue, wait, priority, and so on) are merged into the call_async keyword arguments.

Raises:



59
60
61
62
63
# File 'lib/servus/events/invocation.rb', line 59

def enqueue
  raise Errors::AsyncBackendMissingError.for(service) unless service.respond_to?(:call_async)

  service.call_async(**params, **async_options)
end

#keyString

A deterministic deduplication key derived from the service class and params. Two invocations with the same key are considered duplicates — the Bus keeps the first and skips the rest.

Options are intentionally excluded: identity is what to call, not how to call it.

Returns:

  • (String)

    SHA-256 hex digest



73
74
75
# File 'lib/servus/events/invocation.rb', line 73

def key
  Digest::SHA256.hexdigest("#{service}:#{params.to_json}")
end