Middleware all the things

A presentation at EuRuKo in September 2017 in Budapest, Hungary by Mehdi Lahmam

Slide 1

Slide 1

Middleware all the things

Slide 2

Slide 2

At Trainline, we sell train tickets, across EU and UK.

Slide 3

Slide 3

Slide 4

Slide 4

Slide 5

Slide 5

How does it work? Frontends Rails API Connections API aka connection with carriers APIs

Slide 6

Slide 6

A bunch of middlewares Requests are processed by generated apps on the fly, which are stacks of middlewares.

Slide 7

Slide 7

Request (an environment Hash) Connections API env[:params][:action] Base::Builder.app do use DoSomething use AnotherThing # insert a bunch of cool stuff here end

Slide 8

Slide 8

Connections API An action (an app) Middleware 1 ① down ↓ ↑ ④ up Middleware 2 ② down ↓ ↑ ③ up Middleware 3 ⃔ → ⑤ env[:callback] ⃔

Slide 9

Slide 9

% tree lib/pacon/actions -L 1 lib/pacon/actions ├── book.rb ├── book_subscription.rb ├── cancel.rb ├── emit.rb ├── emit_subscription.rb ├── estimate_exchange.rb ├── estimate_refund.rb ├── exchange.rb ├── exchange_pay.rb ├── exchange_search.rb ├── fetch_pnr.rb ├── fetch_subscription.rb ├── fetch_travel_document.rb ├── immediate_cancel.rb ├── load_timetable.rb ├── pay.rb ├── refund.rb └── search.rb

Slide 10

Slide 10

def self.search Base::Builder.app do use Base::LogAction use Base::VolatileStations use Base::InitResultCache use Base::LogSearchFruitfulness use Base::AvoidFruitlessSearch use Base::ReportAndBlockCombinations use Base::TryAgain use Base::SearchWindow use Base::FilterUnsellableFolderMix use Base::FilterTimetableResults use Base::TooManyPassengers use Base::WarnDifferentStation use Base::Parallel end end

Slide 11

Slide 11

def self.search Base::Builder.app do use Base::LogAction use Base::VolatileStations use Base::InitResultCache use Base::LogSearchFruitfulness use Base::AvoidFruitlessSearch use Base::ReportAndBlockCombinations use Base::TryAgain use Base::SearchWindow use Base::FilterUnsellableFolderMix use Base::FilterTimetableResults use Base::TooManyPassengers use Base::WarnDifferentStation use Base::Parallel end end Will call SNCF.search, DB.search…

Slide 12

Slide 12

module SNCF class << self def search Base::Builder.app do use SNCF::Stations use SNCF::ExtractFoldersFromJourneys # tons of very secret sauce use SNCF::HttpRequest end end end end

Slide 13

Slide 13

Event Machine FTW The whole is based on Event Machine to coordinate all the parallel requests made to carriers APIs.