SlideShare ist ein Scribd-Unternehmen logo
1 von 55
Downloaden Sie, um offline zu lesen
Text
!
THREAD
SAFETY
FIRST
Emily Stolfo
Ruby Engineer at , Adjunct Faculty at Columbia
@EmStolfo
There is no such thing as
thread-safe Ruby code.
Ruby Engineer at
Adjunct Faculty at Columbia
Expert
Emily Stolfo
require 'set'
members = Set.new
threads = []
200.times do |n|
threads << Thread.new do
if n % 2 == 0
members << n
else
members.first.nil?
end
end
end
threads.each(&:join)
Demo code
Inconsistent bug?
2.0 with 200 threads
JRuby with 10 threads
JRuby with 200 threads
âś”
đť™­
âś”
1. Concurrency in Ruby
! THREAD SAFETY FIRST
3. Testing concurrency
2. Writing thread-safe code
CONCURRENCY IN RUBY
There are different
Ruby implementations.
Threads are like
music.
GIL
green thread
native (OS) thread
ruby 1.8
Threads and Ruby
Instruments: OS threads
Notes: green threads
Conductor: GIL
ruby 1.9+
Instruments: OS threads
Notes: green threads
Conductor: GIL
Threads and Ruby
JRuby
Instruments: OS threads
Notes: green threads
Threads and Ruby
Different Rubies?
Different semantics.
Our code
sometimes works by
sheer luck.
You’re lucky your code
hasn’t run on JRuby.
You’re lucky
there is a GIL.
Example:
MongoDB Ruby driver
and Replica Sets
MongoDB Replica Set Creation
MongoDB Replica Set
MongoDB Replica Set Failure
MongoDB Replica Set Recovery
MongoDB Replica Set Recovered
Mutable shared state.
class ReplicaSetClient
def initialize
@nodes = Set.new
end
...
def connect_to_nodes
seed = valid_node
seed.node_list.each do |host|
node = Node.new(host)
@nodes << node if node.connect
end
end
def choose_node(type)
@nodes.detect { |n| n.type == type }
end
end
Ruby driver
class ReplicaSetClient
def initialize
@nodes = Set.new
end
...
def connect_to_nodes
seed = valid_node
seed.node_list.each do |host|
node = Node.new(host)
@nodes << node if node.connect
end
end
def choose_node(type)
@nodes.detect { |n| n.type == type }
end
end
Potential concurrency bug
(RuntimeError)
"can't add a new key into
hash during iteration"
We often use
hashes as caches.
Hashes and their
derivatives are not
thread-safe in JRuby.
!
How do we write this
code thread-safely?
WRITING
THREAD-SAFE CODE
Shared data:
Avoid across threads.
If you can’t avoid shared
data, at least avoid
shared mutable data.
If you can’t avoid
shared mutable data,
use concurrency primitives.
The top 2
concurrency primitives
class ReplicaSetClient
def initialize
@nodes = Set.new
@connect_mutex = Mutex.new
end
...
def connect_to_nodes
seed = valid_node
seed.node_list.each do |host|
node = Node.new(host)
@connect_mutex.synchronize do
@nodes << node if node.connect
end
end
end
def choose_node(type)
@connect_mutex.synchronize do
@nodes.detect { |n| n.type == type }
end
end
end
1. Mutex
class ReplicaSetClient
def initialize
@nodes = Set.new
@connect_mutex = Mutex.new
end
...
def connect_to_nodes
seed = valid_node
seed.node_list.each do |host|
node = Node.new(host)
@connect_mutex.synchronize do
@nodes << node if node.connect
end
end
end
def choose_node(type)
@connect_mutex.synchronize do
@nodes.detect { |n| n.type == type }
end
end
end
1. Mutex
Use to isolate code
that should be
executed by at most
one thread at a time.
shared
replica
set
state
update
A mutex is not magic.
Avoid locking
around I/O.
class ReplicaSetClient
def initialize
@nodes = Set.new
@connect_mutex = Mutex.new
end
...
def connect_to_nodes
seed = valid_node
seed.node_list.each do |host|
node = Node.new(host)
@connect_mutex.synchronize do
@nodes << node if node.connect
end
end
end
def choose_node(type)
@connect_mutex.synchronize do
@nodes.detect { |n| n.type == type }
end
end
end
1. Mutex
network
I/O
class ReplicaSetClient
def initialize
@nodes = Set.new
@connect_mutex = Mutex.new
end
...
def connect_to_nodes
seed = valid_node
seed.node_list.each do |host|
node = Node.new(host)
@connect_mutex.synchronize do
@nodes << node
end if node.connect
end
end
def choose_node(type)
@connect_mutex.synchronize do
@nodes.detect { |n| n.type == type }
end
end
end
1. Mutex
network
I/O
Consider resources.
Ex: Thundering herd
Thundering herd
n threads are woken up after waiting on something,
but only 1 can continue. Waste of system resources
to wake up n threads.
Consider your system.
Ex: Queued requests
App
server
Think systemically.
n threads are waiting to write to the replica set
primary. The primary is flooded with requests when
the replica set state is refreshed.
App
server
2. Condition Variable
Use to communicate between threads.
class Pool
def initialize
@socket_available = ConditionVariable.new
...
end
def checkout
loop do
@lock.synchronize do
if @available_sockets.size > 0
socket = @available_sockets.next
return socket
end
@socket_available.wait(@lock)
end
end
end
def checkin(socket)
@lock.synchronize do
@available_sockets << socket
@socket_available.
end
end
end
Condition Variable
broadcast
Why is this
a waste of
system
resources?
class Pool
def initialize
@socket_available = ConditionVariable.new
...
end
def checkout
loop do
@lock.synchronize do
if @available_sockets.size > 0
socket = @available_sockets.next
return socket
end
@socket_available.wait(@lock)
end
end
end
def checkin(socket)
@lock.synchronize do
@available_sockets << socket
@socket_available.
end
end
end
Condition Variable
signal
Only one
thread
can
continue
TESTING CONCURRENCY
Testing
1. Test with different implementations.
2. Test with a ton of threads.
3. Use patterns for precision.
require 'set'
members = Set.new
threads = []
10.times do |n|
threads << Thread.new do
if n % 2 == 0
members << n
else
members.first.nil?
end
end
end
threads.each(&:join)
Test with a ton of threads.
require 'set'
members = Set.new
threads = []
200.times do |n|
threads << Thread.new do
if n % 2 == 0
members << n
else
members.first.nil?
end
end
end
threads.each(&:join)
Test with a ton of threads.
Use synchronization
methods if you need
more precision.
ex: rendezvous / barrier
pattern
Concurrency in Ruby
Know your implementations.
!
Know your concurrency primitives.
!
Know your code.
”thread-safe JRuby 1.7.4 code”
!
Thanks
Emily Stolfo
@EmStolfo

Weitere ähnliche Inhalte

Andere mochten auch

Threads in Ruby (Basics)
Threads in Ruby (Basics)Threads in Ruby (Basics)
Threads in Ruby (Basics)varunlalan
 
Concurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple SpacesConcurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple Spacesluccastera
 
Threading and Concurrency in Ruby
Threading and Concurrency in RubyThreading and Concurrency in Ruby
Threading and Concurrency in RubyTim Raymond
 
Treading the Rails with Ruby Shoes
Treading the Rails with Ruby ShoesTreading the Rails with Ruby Shoes
Treading the Rails with Ruby ShoesEleanor McHugh
 
Multi-threaded web crawler in Ruby
Multi-threaded web crawler in RubyMulti-threaded web crawler in Ruby
Multi-threaded web crawler in RubyPolcode
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threadsmperham
 
The Top Skills That Can Get You Hired in 2017
The Top Skills That Can Get You Hired in 2017The Top Skills That Can Get You Hired in 2017
The Top Skills That Can Get You Hired in 2017LinkedIn
 

Andere mochten auch (7)

Threads in Ruby (Basics)
Threads in Ruby (Basics)Threads in Ruby (Basics)
Threads in Ruby (Basics)
 
Concurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple SpacesConcurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple Spaces
 
Threading and Concurrency in Ruby
Threading and Concurrency in RubyThreading and Concurrency in Ruby
Threading and Concurrency in Ruby
 
Treading the Rails with Ruby Shoes
Treading the Rails with Ruby ShoesTreading the Rails with Ruby Shoes
Treading the Rails with Ruby Shoes
 
Multi-threaded web crawler in Ruby
Multi-threaded web crawler in RubyMulti-threaded web crawler in Ruby
Multi-threaded web crawler in Ruby
 
Actors and Threads
Actors and ThreadsActors and Threads
Actors and Threads
 
The Top Skills That Can Get You Hired in 2017
The Top Skills That Can Get You Hired in 2017The Top Skills That Can Get You Hired in 2017
The Top Skills That Can Get You Hired in 2017
 

Ă„hnlich wie Thread Safety in Ruby Code

what every web and app developer should know about multithreading
what every web and app developer should know about multithreadingwhat every web and app developer should know about multithreading
what every web and app developer should know about multithreadingIlya Haykinson
 
Top 30 Node.js interview questions
Top 30 Node.js interview questionsTop 30 Node.js interview questions
Top 30 Node.js interview questionstechievarsity
 
The Ruby Guide to *nix Plumbing: Hax0R R3dux
The Ruby Guide to *nix Plumbing: Hax0R R3duxThe Ruby Guide to *nix Plumbing: Hax0R R3dux
The Ruby Guide to *nix Plumbing: Hax0R R3duxEleanor McHugh
 
Ruby -the wheel Technology
Ruby -the wheel TechnologyRuby -the wheel Technology
Ruby -the wheel Technologyppparthpatel123
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...bobmcwhirter
 
How to discover the Ruby's defects with web application
How to discover the Ruby's defects with web applicationHow to discover the Ruby's defects with web application
How to discover the Ruby's defects with web applicationHiroshi SHIBATA
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tourcacois
 
Zookeeper big sonata
Zookeeper  big sonataZookeeper  big sonata
Zookeeper big sonataAnh Le
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)tarcieri
 
Parallel Programming: Beyond the Critical Section
Parallel Programming: Beyond the Critical SectionParallel Programming: Beyond the Critical Section
Parallel Programming: Beyond the Critical SectionTony Albrecht
 
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9Ilya Grigorik
 
Thread priorities in java
Thread priorities in javaThread priorities in java
Thread priorities in javaDucat India
 
Pfm technical-inside
Pfm technical-insidePfm technical-inside
Pfm technical-insideiyatomi takehiro
 
MERIMeeting du 27 mai 2014 - Parallel Programming
MERIMeeting du 27 mai 2014 - Parallel ProgrammingMERIMeeting du 27 mai 2014 - Parallel Programming
MERIMeeting du 27 mai 2014 - Parallel ProgrammingOlivier NAVARRE
 
Intro To .Net Threads
Intro To .Net ThreadsIntro To .Net Threads
Intro To .Net Threadsrchakra
 
Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010aaronmorton
 

Ă„hnlich wie Thread Safety in Ruby Code (20)

what every web and app developer should know about multithreading
what every web and app developer should know about multithreadingwhat every web and app developer should know about multithreading
what every web and app developer should know about multithreading
 
Top 30 Node.js interview questions
Top 30 Node.js interview questionsTop 30 Node.js interview questions
Top 30 Node.js interview questions
 
The Ruby Guide to *nix Plumbing: Hax0R R3dux
The Ruby Guide to *nix Plumbing: Hax0R R3duxThe Ruby Guide to *nix Plumbing: Hax0R R3dux
The Ruby Guide to *nix Plumbing: Hax0R R3dux
 
Ruby -the wheel Technology
Ruby -the wheel TechnologyRuby -the wheel Technology
Ruby -the wheel Technology
 
concurrency
concurrencyconcurrency
concurrency
 
Java Threads
Java ThreadsJava Threads
Java Threads
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
 
How to discover the Ruby's defects with web application
How to discover the Ruby's defects with web applicationHow to discover the Ruby's defects with web application
How to discover the Ruby's defects with web application
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 
Zookeeper big sonata
Zookeeper  big sonataZookeeper  big sonata
Zookeeper big sonata
 
Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)Concurrent programming with Celluloid (MWRC 2012)
Concurrent programming with Celluloid (MWRC 2012)
 
Shell scripting
Shell scriptingShell scripting
Shell scripting
 
Parallel Programming: Beyond the Critical Section
Parallel Programming: Beyond the Critical SectionParallel Programming: Beyond the Critical Section
Parallel Programming: Beyond the Critical Section
 
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
 
Thread priorities in java
Thread priorities in javaThread priorities in java
Thread priorities in java
 
Pfm technical-inside
Pfm technical-insidePfm technical-inside
Pfm technical-inside
 
MERIMeeting du 27 mai 2014 - Parallel Programming
MERIMeeting du 27 mai 2014 - Parallel ProgrammingMERIMeeting du 27 mai 2014 - Parallel Programming
MERIMeeting du 27 mai 2014 - Parallel Programming
 
Intro To .Net Threads
Intro To .Net ThreadsIntro To .Net Threads
Intro To .Net Threads
 
Lec7
Lec7Lec7
Lec7
 
Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010Nzpug welly-cassandra-02-12-2010
Nzpug welly-cassandra-02-12-2010
 

KĂĽrzlich hochgeladen

The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 

KĂĽrzlich hochgeladen (20)

The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 

Thread Safety in Ruby Code