Class: Desiru::GraphQL::DataLoader::Promise
- Inherits:
-
Object
- Object
- Desiru::GraphQL::DataLoader::Promise
- Defined in:
- lib/desiru/graphql/data_loader.rb
Overview
Thread-safe Promise implementation for lazy loading
Instance Method Summary collapse
- #fulfill(value) ⇒ Object
- #fulfilled? ⇒ Boolean
-
#initialize(&block) ⇒ Promise
constructor
A new instance of Promise.
- #reject(error) ⇒ Object
- #rejected? ⇒ Boolean
- #then(&block) ⇒ Object
- #value(timeout: nil) ⇒ Object
Constructor Details
#initialize(&block) ⇒ Promise
Returns a new instance of Promise.
285 286 287 288 289 290 291 292 293 |
# File 'lib/desiru/graphql/data_loader.rb', line 285 def initialize(&block) @mutex = Mutex.new @condition = ConditionVariable.new @fulfilled = false @value = nil @error = nil @callbacks = [] block&.call(self) end |
Instance Method Details
#fulfill(value) ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/desiru/graphql/data_loader.rb', line 295 def fulfill(value) callbacks_to_run = nil @mutex.synchronize do return if @fulfilled @value = value @fulfilled = true callbacks_to_run = @callbacks.dup @callbacks.clear # Signal all waiting threads @condition.broadcast end # Run callbacks outside the mutex to avoid deadlock callbacks_to_run&.each { |cb| cb.call(value) } end |
#fulfilled? ⇒ Boolean
367 368 369 |
# File 'lib/desiru/graphql/data_loader.rb', line 367 def fulfilled? @mutex.synchronize { @fulfilled } end |
#reject(error) ⇒ Object
314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/desiru/graphql/data_loader.rb', line 314 def reject(error) @mutex.synchronize do return if @fulfilled @error = error @fulfilled = true @callbacks.clear # Signal all waiting threads @condition.broadcast end end |
#rejected? ⇒ Boolean
371 372 373 |
# File 'lib/desiru/graphql/data_loader.rb', line 371 def rejected? @mutex.synchronize { @fulfilled && !@error.nil? } end |
#then(&block) ⇒ Object
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'lib/desiru/graphql/data_loader.rb', line 327 def then(&block) run_immediately = false value_to_pass = nil @mutex.synchronize do if @fulfilled && !@error run_immediately = true value_to_pass = @value elsif !@fulfilled @callbacks << block end end # Run callback outside mutex if already fulfilled block.call(value_to_pass) if run_immediately self end |
#value(timeout: nil) ⇒ Object
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/desiru/graphql/data_loader.rb', line 346 def value(timeout: nil) @mutex.synchronize do if timeout end_time = Time.now + timeout until @fulfilled remaining = end_time - Time.now break if remaining <= 0 @condition.wait(@mutex, remaining) end else @condition.wait(@mutex) until @fulfilled end raise @error if @error raise "Promise not yet fulfilled" unless @fulfilled @value end end |