wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln...

68
production haskell Reid Draper @reiddraper wrangling the internet of things with haskell

Transcript of wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln...

Page 1: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

production haskell

Reid Draper @reiddraper

wrangling the internet of things with haskell

Page 2: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

production haskell

Reid Draper @reiddraper

Page 3: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

production haskell today

Page 4: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

production haskell at helium12 months in

Page 5: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

lowest defect rate

Page 6: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

easiest to refactorlowest defect rate

Page 7: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

OSS libraries for everything*most enjoyable

easiest to refactorlowest defect rate

Page 8: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

20k LOC

Page 9: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

5 developers20k LOC

Page 10: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

6 production services5 developers

20k LOC

Page 11: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 12: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 13: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

cabal hell

Page 14: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

cabal hell

Page 15: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

stackhaskellstack.org

Page 16: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz
Page 17: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

project specificsnapshot

ghc packages

Page 18: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz
Page 19: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

2 seconds20k LOC

Page 20: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz
Page 21: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

ordealgithub.com/reiddraper/ordeal

Page 22: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

stack build self-contained

executable

Page 23: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 24: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

app!"" assets#   !"" images#   #   %"" favicon.ico#   !"" javascript#   #   %"" site.js#   %"" stylesheet#   %"" site.css%"" bin %"" app

Page 25: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

restart appln -s app-370b347 currenttar -xzf app-370b347.tgz

Page 26: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

restart appln -s app-83181ad current

Page 27: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

60MB

Page 28: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz
Page 29: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 30: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

ekg

Page 31: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz
Page 32: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

stdout file syslog

Page 33: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 34: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

QuickCheck

Page 35: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

propEvent :: Event -> BoolpropEvent a = Just a == decode (encode a)

Page 36: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

Event roundtrips in JSON: FAIL (0.04s) *** Failed! Falsifiable (after 1 test): Event {_severity = Error, _facility = Unspecified, _sampled = 1894-02-22 00:00:04.5986 UTC, _eventDetails = ElementDisconnect {_elementMAC = 8ec52584b2c82424}, _eventMessage = Nothing, _originator = http://www.ietf.org/rfc/rfc2396.txt, _reference = Just http://www.ietf.org/rfc/rfc2396.txt }

Page 37: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

Event roundtrips in JSON: FAIL (0.04s) *** Failed! Falsifiable (after 1 test): Event {_severity = Error, _facility = Unspecified, _sampled = 1894-02-22 00:00:04.5986 UTC, _eventDetails = ElementDisconnect {_elementMAC = 8ec52584b2c82424}, _eventMessage = Nothing, _originator = http://www.ietf.org/rfc/rfc2396.txt, _reference = Just http://www.ietf.org/rfc/rfc2396.txt }

Page 38: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

ghci> t1894-02-22 00:00:04.5986 UTCghci> Data.Aeson.encode t"\"1894-02-22T00:00:04.598Z\""

Page 39: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 40: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

postgresql-transactionalgithub.com/helium/postgresql-transactional

Page 41: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

lookupUser emailAddress = queryFirst [emailAddress] [sql| SELECT id, email, name, timezone FROM user_account WHERE email = ? |]

Page 42: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

Page 43: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

Page 44: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

Page 45: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

quz

Page 46: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

quz

buz

Page 47: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

quz

buz

fiz

Page 48: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

BEGINBEGINCOMMITCOMMIT

Page 49: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

BEGINBEGINCOMMITCOMMIT

Page 50: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

BEGINBEGINCOMMITCOMMIT

Page 51: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

WARNING:  there is already a transaction in progressWARNING:  there is no transaction in progress

Page 52: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

quz

buz

fiz

Page 53: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

quz

buz

fiz

Page 54: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

foo

bar

baz

quz

buz

Page 55: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

lookupUser :: Connection -> Text -> IO (Maybe User)lookupUser connection emailAddress = queryFirst [emailAddress] [sql| SELECT id, email, name, timezone FROM user_account WHERE email = ? |] connection

Page 56: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

createUser :: Connection -> NewUser -> IO User

createOrganization :: Connection -> NewOrganization -> IO Organization

addUserToOrganization :: Connection -> User -> Organization -> IO ()

Page 57: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

createUserAndOrganization :: Connection -> NewUser -> IO ()createUserAndOrganization connection newUser = withTransaction connection $ do let newOrganization = NewOrganization (newUser ^. name) user <- createUser connection newUser org <- createOrganization connection newOrganization addUserToOrganization connection user org

Page 58: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

-- NOTE: you MUST wrap this in a transaction!!createUserAndOrganization :: Connection -> NewUser -> IO ()createUserAndOrganization connection newUser = do let newOrganization = NewOrganization (newUser ^. name) user <- createUser connection newUser org <- createOrganization connection newOrganization addUserToOrganization connection user org

Page 59: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

withTransaction conn $ do createUserAndOrganization conn newUser somethingElse conn

Page 60: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

types to the rescue

Page 61: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

lookupUser :: Connection -> Text -> IO (Maybe User)lookupUser :: Text -> PGTransaction (Maybe User)

Page 62: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

runPGTransaction :: PGTransaction a -> Postgres.Connection -> IO a

Page 63: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

createUserAndOrganization :: NewUser -> PGTransaction ()createUserAndOrganization newUser = let newOrganization = NewOrganization (newUser ^. name) user <- createUser newUser org <- createOrganization newOrganization addUserToOrganization user org

foo = do createUserAndOrganization newUser somethingElse

runPGTransaction foo connection

Page 64: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

notAllowed = do user <- createUser newUser someSlowSideEffectingThing return user

Page 65: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

notAllowed = do user <- createUser newUser someSlowSideEffectingThing :: IO () return user

Page 66: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

postgresql-transactionalgithub.com/helium/postgresql-transactional

Page 67: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

build deploy monitor test develop

Page 68: wrangling the internet of things with haskell production haskell · 2019-09-23 · restart app ln -s app-370b347 current tar -xzf app-370b347.tgz

Reid Draper @reiddrapergithub.com/helium

helium.com