Slide 1

Slide 1 text

Process tons of jobs with Swift Tokyo Server Side Swift meetup 2017.06.27 @ainame

Slide 2

Slide 2 text

Self-intro ● Satoshi Namai ○ https://github.com/ainame ○ https://twitter.com/ainame ● iOS Engineer? ● Love Ruby and Swift ● Heavy user of sidekiq gem for tons of background jobs in previous job

Slide 3

Slide 3 text

Agenda ● My motivation ● About sidekiq gem ● ainame/Lumpik ● vs Crystal-lang ● Redis client

Slide 4

Slide 4 text

My motivation ● SSS(Server Side Swift) is very very very hard!! ○ Can’t keep writing without enthusiasm ○ It’s fun for me. ● Learn not only Swift but also the System Programming ○ Swift has compatibility for C-APIs, we can write applications with low-level APIs. ● Be a Hacker ○ Few people try ○ This is an opportunity

Slide 5

Slide 5 text

SSS except Web ● There are many Web app frameworks in Swift ○ Kitura, Vapor, Zewo, Perfect, etc… ○ https://github.com/swift-server/http ● How about the background job processing? ○ There’s nothing? ○ Opportunity for me

Slide 6

Slide 6 text

Background job processing ● works with Web app normaly ○ Web app should respond for the client quickly ● works for the time-consuming tasks ○ UPDATE query ○ send push/e-mail notifications ○ video encoding/image processing etc...

Slide 7

Slide 7 text

Redis Web/Rails app Cron/Rails runner One-off scripts Worker Worker Worker Worker

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Sidekiq ● Fastest Ruby’s job system for general purpose ○ works with Redis as a queue for jobs ○ works with rails well ● Why many rubyists choose sidekiq? ○ less memory & low latency ○ nice web admin ○ Pro/Enterprise Support!! http://sidekiq.org/about

Slide 11

Slide 11 text

https://www.indiehackers.com/businesses/sidekiq

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Inside Sidekiq ● Sidekiq has 3 main modules ○ Processor - fetches a job and executes a worker on dedicated thread ○ Poller - poll and enqueue jobs to retry ○ Heatbeat - send statictics metadata to Redis (lib/sidekiq/launcher.rb) ● Definition: Processor/Worker/Job ○ Job is data like arguments of function for Worker ○ Worker is the PORO what you want to do ○ Processor fetches a job and executes

Slide 14

Slide 14 text

Redis Poller Heatbeat Processor Processor Processor Processor Worker Worker Worker Worker Job Job Job Job Manager Manage retried jobs ● re-enqueue retry jobs ● adjust polling intervals by the number of processes Send process statuses for the admin ● How many do processors work? ● How many did jobs succeeded/failed? ● What job dose processor work with now? Fetch

Slide 15

Slide 15 text

FIFO queue on the Redis light jobs id=5 id=7 id=27 …. id=58 heavy “abc” “swift” “fuga” …. “ios” > RPUSH “light” 58 > RPUSH “heavy” “ios” > BRLPOP “light” “heavy” 2 id=5 Fetch a job from two queues Append a job to light queue

Slide 16

Slide 16 text

ainame/Lumpik

Slide 17

Slide 17 text

ainame/Lumpik Sidekiq clone on the Swift ● Fastest Swift’s job queue system for general purpose? ● Type-safe arguments ● Good concurrency with GCD ● Compatibiity for sidekiq-web

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Dependencies ● vapor/redis・・・ Redis client ● ainame/Swift-Daemon・・・Damonize a process ● IBM-Swift/BlueSignals・・・Handle signals ● SwiftBeaver/SwiftBeaver・・・Logger ● kylef/Commander・・・Option parser ● jpsim/Yams・・・YAML

Slide 21

Slide 21 text

ainame/Swift-Daemon ● Daemonize a Swift process ● How to detach a process from the shell 1. fork 2. setsid 3. dup2 ● Learn from ruby/ruby

Slide 22

Slide 22 text

Invoke a specified worker from String Swift can’t instatiate any class from String → Generate Router class from source code with Sourcery

Slide 23

Slide 23 text

How to use ainame/Lumpik $ swift package init $ emacs Package.swift $ swift package resolve $ emacs xxxx/main.swift ... $ brew install sourcery $ sourcery --sources xxx --templates Templates --output xxx

Slide 24

Slide 24 text

Demo

Slide 25

Slide 25 text

ainame/Lumpik is a WIP ● Not implemented yet several features ○ dead queue ○ scheduled queue ● Targets for Swift 4 ○ faster String APIs ○ adopt Codable/JSONEncoder, but Swift doesn’t support it on the Linux currently ● Cloud be faster than sidekiq.cr ○ make faster Redis client in Swift

Slide 26

Slide 26 text

vs sidekiq.cr Original author, @mperham makes faster sidekiq on the Crystal-lang ● Pros ○ mperham/sidekiq.cr is really fast ○ ruby like syntax ○ very fast ● Cons ○ doesn’t work CPU intensive jobs well by multithreading

Slide 27

Slide 27 text

Benchmarks crystal-redis client is crasy fast... Redis: Crystal vs Ruby vs Node vs ... https://www.stefanwille.com/2015/05/redis-clients-crystal-vs-ruby-vs-c-vs-go/ https://github.com/stefanwille/redis-client-benchmarks https://github.com/ainame/vapor-redis-benchmark I have a plan to make more faster Redis client than crystal-redis but it’s difficult for several reasons...

Slide 28

Slide 28 text

What I want for Redis client in Swift ● Prefer method signature to enum based signature for command definition ○ redis.set(“key”, value) vs redis.command(.set, [“key”, value]) ● Prefer real typed value to enum based value for response ○ get(_ key: String) throws -> String vs get(_ key: String) -> ResponseValue ● Pipelining / MULTI-EXEC transaction ○ Pipelining is a basic technique to speedup ● Using buffered IO based TCP client ○ buffered IO is also basic technique to speedup

Slide 29

Slide 29 text

Recap ● Sidekiq is one of the most successful OSS ● Learn how to make good middleware with 写経 ● Swift dosen’t suit for system programming now ● We have to create fast and easy IO library like Ruby or Crystal

Slide 30

Slide 30 text

Enjoy Server Side Swift!