Class: SolidObjects::Client
- Inherits:
-
Object
- Object
- SolidObjects::Client
- Defined in:
- lib/solid_objects/client.rb,
sig/generated/lib/solid_objects/client.rbs
Instance Attribute Summary collapse
-
#mailbox ⇒ Object
readonly
Returns the value of attribute mailbox.
Instance Method Summary collapse
- #ask(reference, message_name, arguments, timeout:, idempotency_key: nil, authorization_context: nil) ⇒ Object
- #authorize!(hook, reference, message_name, arguments, authorization_context:) ⇒ void
- #authorize_destroy!(reference, authorization_context:) ⇒ void
- #destroy(reference, authorization_context: nil) ⇒ Boolean
-
#initialize(mailbox: Mailbox.new) ⇒ Client
constructor
A new instance of Client.
- #monotonic_now ⇒ Float
- #tell(reference, message_name, arguments, available_at: nil, idempotency_key: nil, authorization_context: nil) ⇒ MessageReference
- #wait_for_result(message_reference, timeout:) ⇒ Object
Constructor Details
Instance Attribute Details
#mailbox ⇒ Object (readonly)
Returns the value of attribute mailbox.
93 94 95 |
# File 'lib/solid_objects/client.rb', line 93 def mailbox @mailbox end |
Instance Method Details
#ask(reference, message_name, arguments, timeout:, idempotency_key: nil, authorization_context: nil) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/solid_objects/client.rb', line 38 def ask(reference, , arguments, timeout:, idempotency_key: nil, authorization_context: nil) actor_class = SolidObjects.registry.fetch(reference.actor_type) = .to_sym query = actor_class.definition.queries.key?() = actor_class.definition..key?() raise UnknownMessage, "unknown message #{.inspect}" unless query || ( query ? SolidObjects.configuration. : SolidObjects.configuration., reference, , arguments, authorization_context: ) = mailbox.enqueue( reference, , arguments, kind: "ask", idempotency_key: ) wait_for_result(, timeout:) end |
#authorize!(hook, reference, message_name, arguments, authorization_context:) ⇒ void
This method returns an undefined value.
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/solid_objects/client.rb', line 96 def (hook, reference, , arguments, authorization_context:) = hook.call( actor_type: reference.actor_type, actor_id: reference.actor_id, message_name: .to_s, arguments:, authorization_context: ) return if raise Unauthorized, "actor invocation is not authorized" end |
#authorize_destroy!(reference, authorization_context:) ⇒ void
This method returns an undefined value.
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/solid_objects/client.rb', line 110 def (reference, authorization_context:) = SolidObjects.configuration..call( actor_type: reference.actor_type, actor_id: reference.actor_id, authorization_context: ) return if raise Unauthorized, "actor destruction is not authorized" end |
#destroy(reference, authorization_context: nil) ⇒ Boolean
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/solid_objects/client.rb', line 63 def destroy(reference, authorization_context: nil) raise ActorCallCycle, "actors cannot synchronously destroy another actor" if Context.current_actor SolidObjects.registry.fetch(reference.actor_type) (reference, authorization_context:) instance_id = SolidObjects.database_adapter.transaction do instance = Instance.lock.find_by( actor_type: reference.actor_type, actor_id: reference.actor_id ) next unless instance instance_id = instance.id instance.delete instance_id end return false unless instance_id SolidObjects.instrument( :"actor.destroyed", instance_id:, actor_type: reference.actor_type, actor_id: reference.actor_id ) SolidObjects.wake_up.signal true end |
#monotonic_now ⇒ Float
149 150 151 |
# File 'lib/solid_objects/client.rb', line 149 def monotonic_now ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end |
#tell(reference, message_name, arguments, available_at: nil, idempotency_key: nil, authorization_context: nil) ⇒ MessageReference
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/solid_objects/client.rb', line 15 def tell(reference, , arguments, available_at: nil, idempotency_key: nil, authorization_context: nil) actor_class = SolidObjects.registry.fetch(reference.actor_type) = .to_sym raise UnknownMessage, "unknown message #{.inspect}" unless actor_class.definition..key?() ( SolidObjects.configuration., reference, , arguments, authorization_context: ) mailbox.enqueue( reference, , arguments, kind: "tell", available_at:, idempotency_key: ) end |
#wait_for_result(message_reference, timeout:) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/solid_objects/client.rb', line 122 def wait_for_result(, timeout:) deadline = monotonic_now + timeout.to_f loop do = Message.uncached { Message.find(.id) } return .result if .completed? if .dead? raise MessageFailed.new( "actor message failed permanently", message_id: .id, details: .error || {} ) end remaining = deadline - monotonic_now raise AskTimeout, "actor request timed out after #{timeout} seconds" unless remaining.positive? SolidObjects.wake_up.wait( timeout: [ remaining, SolidObjects.configuration.ask_polling_interval ].min ) end rescue ActiveRecord::RecordNotFound raise ActorDestroyed, "actor was destroyed while waiting for its result" end |