Module: FlowChat::GatewayAsyncSupport

Overview

Concern for gateways to support async background processing Mix this into gateway classes to enable async detection and job enqueueing

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



7
8
9
# File 'lib/flow_chat/gateway_async_support.rb', line 7

def context
  @context
end

#controllerObject (readonly)

Returns the value of attribute controller.



7
8
9
# File 'lib/flow_chat/gateway_async_support.rb', line 7

def controller
  @controller
end

Instance Method Details

#async_supported?Boolean

Check if gateway supports async processing Override in gateways that don't support async (e.g., USSD)

Returns:

  • (Boolean)


11
12
13
# File 'lib/flow_chat/gateway_async_support.rb', line 11

def async_supported?
  true
end

#enqueue_async_jobObject

Enqueue background job with serialized request context Returns true if job was enqueued, false otherwise



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/flow_chat/gateway_async_support.rb', line 35

def enqueue_async_job
  return false unless should_enqueue_async?

  processor = @context["processor"]

  FlowChat.logger.info { "#{self.class.name}: Async enabled - enqueuing background job" }

  # Serialize request data for BackgroundController
  request_data = {
    params: @controller.request.params.to_h,
    method: @controller.request.method,
    headers: extract_headers_for_background(@controller.request),
    host: extract_host(@controller.request),
    path: extract_path(@controller.request),
    body: extract_body_for_background(@controller.request),
    remote_ip: extract_remote_ip(@controller.request)
  }

  # Enqueue user's job with request context and job params
  processor.async_job_class.perform_later(
    request_context: request_data,
    **processor.async_job_params
  )

  FlowChat.logger.info { "#{self.class.name}: Background job enqueued successfully" }

  true
end

#extract_body_for_background(request) ⇒ Object

Extract request body for background processing Override in gateways that need the request body



89
90
91
92
93
94
95
96
97
# File 'lib/flow_chat/gateway_async_support.rb', line 89

def extract_body_for_background(request)
  return nil unless request.body

  body_content = request.body.read
  request.body.rewind  # Reset for subsequent reads
  body_content
rescue
  nil
end

#extract_headers_for_background(request) ⇒ Object

Extract serializable headers needed for background processing Override in gateways that need additional headers



66
67
68
69
70
71
# File 'lib/flow_chat/gateway_async_support.rb', line 66

def extract_headers_for_background(request)
  {
    "Content-Type" => request.headers["Content-Type"],
    "User-Agent" => request.headers["User-Agent"]
  }.compact
end

#extract_host(request) ⇒ Object

Extract host from request for URL boundary support



74
75
76
77
78
# File 'lib/flow_chat/gateway_async_support.rb', line 74

def extract_host(request)
  request.host
rescue
  nil
end

#extract_path(request) ⇒ Object

Extract path from request for URL boundary support



81
82
83
84
85
# File 'lib/flow_chat/gateway_async_support.rb', line 81

def extract_path(request)
  request.path
rescue
  nil
end

#extract_remote_ip(request) ⇒ Object

Extract remote IP from request



100
101
102
103
104
# File 'lib/flow_chat/gateway_async_support.rb', line 100

def extract_remote_ip(request)
  request.remote_ip
rescue
  nil
end

#in_background?Boolean

Detect if we're currently in background mode

Returns:

  • (Boolean)


16
17
18
# File 'lib/flow_chat/gateway_async_support.rb', line 16

def in_background?
  @controller.is_a?(::FlowChat::BackgroundController)
end

#should_enqueue_async?Boolean

Check if async processing should be used Returns true if:

  • Not already in background mode
  • Processor has async enabled
  • Gateway supports async

Returns:

  • (Boolean)


25
26
27
28
29
30
31
# File 'lib/flow_chat/gateway_async_support.rb', line 25

def should_enqueue_async?
  processor = @context["processor"]

  !in_background? &&
    processor&.async_enabled? &&
    async_supported?
end