TIL, 2018-06-01, The Saga Pattern
Applying the Saga Pattern (Great Talk!)
[Reference]((https://www.youtube.com/watch?v=xDuwrtwYHu8)
Confusion about Saga pattern
- Saga is a failure management pattern. Sagas are an approach to handling system failures in long-running transactions.
- It is not a state machine (state machine is a set of well-defined states, where transition between states is initiated by triggering an action.)
- Workflow: where transition between them occurs when the previous activity is completed. This includes branching to other activities.
- Saga: Multiple workflows, each providing compensating actions for every step of the workflow where it can fail. Sagas are not necessarily implemented using workflows.
- Sagas are for handling long-running transactions/and their cancellation, and is a process manager, managing orchestration between different bounded contexts that don’t share any dependency.
Saga: How to implement complex business transactions without two phase commit.
- In Domain Driven Design (DDD) the pattern is well known as you need to apply it as soon as you have use cases involving multiple bounded contexts to collaborate.
- In the microservice community it is less known but necessary whenever an overall flow involves multiple services.
- Saga includes state handling + remembering what you did.
- What you need:
- Durable Saga log.
- SEC Process (Saga Execution Coordinator).
- Idempotence of compensating actions.
Importing data and handling conflicts in Ruby on Rails applications
- We can do a
on_duplicate_key_update
thingie to specify that we want to updatename
when a duplicate is found. - If the data being inserted would cause a duplicate, then MySQL will perform an
UPDATE
on the existing row.
Author.import(
[:name, :key],
rows_to_import_second,
on_duplicate_key_update: [:name],
validate: false
)
- On how to detect duplicates:
columns: [:name], conflict_target
RailsConf 2017 Panel: Performance, Performance
- Measure it first boys. Each Ruby object gets a slot in the Ruby VM.
- Discourse: Sam has a blog post on this thing.
- Defer JS, CDN.
- Low request variance on seconds thingie.
- Slowest endpoints that have a high amount of traffic.
- Freezing fucking strings?
- Fast vs pretty code?
- The thing about freeze is that if you don’t really use the string more than once, why?
- Strike-proof.
- Thing that can cause a slow thing in production: Data in the database. Also when one specific user is logged in. Like paper trail.
- Chrome Dev Tools for throttling your network connection.
Musings, Ruby
- Sifter Class
- AR’s merge does a no-op if you merge
nil
. So you can still chainSifter
scopes that we do not want applied. - So you can have an
apply_scopes
where you slowly inject the scopes.
- AR’s merge does a no-op if you merge
- Keeping JSON Key Casing Consistent.
- Olive Branch: used to ensure that JSON keys were lower camel case by the time the front-end received an HTTP response.
Hash#deep_transform_keys
exists, where you convert a hash’s keys via the block operation.- ActiveRecord::Suppress exists. (I don’t like it.)
- Stripe is building a Ruby typechecker
- Facebook’s Flow and MS’s TypeScript added stability to a famously “loose”language.
- Ruby typechecker: Sorbet.
- 9 months of work by 3 people. Real thing, ruins over all code of Stripe.
- Focus on practicality, designed with nice error messages, local type inference, no need to declare local variables, non-nillable types by default, smart control-flow dependent typing, union/intersection types.