agrafix / Spock

Another Haskell web framework for rapid development
https://www.spock.li
678 stars 56 forks source link

Cloud Haskell + Spock #95

Closed brezal closed 7 years ago

brezal commented 7 years ago

In the Elixir ecosystem, Phoenix is an OTP app, and you can build your application as an umbrella project and then import it into Phoenix.

This talk goes into greater detail. http://www.elixirconf.eu/elixirconf2016/lance-halvorsen

I'd like to see the equivalent functionality with Spock, potentially making use of Cloud Haskell.

Thoughts?

agrafix commented 7 years ago

Sorry for the late reply, I was on vacation.

This sounds very interesting, but before I can say anything useful I have to read up on Cloud Haskell and on Phoenix/Elixir and the talk. For the case of "distributed web app" it always depends on what level of abstraction you would like to distribute the work. Maybe you can give an example what you'd like to see?

dpwiz commented 7 years ago

I've done distributed-process app with a WAI server. Nothing fancy, really. Just put your LocalNode into web server environment and have a wrapper to talk to it.

I had a websocket endpoint tied to a user session process once. It's a fun thing to write.

brezal commented 7 years ago

@wiz I don't exactly follow. An example would be useful if you have one, otherwise, what are the steps for putting a LocalNode into a web server environment, and what functionality would a wrapper provide?

brezal commented 7 years ago

@agrafix, I don't have an example to offer currently, but I will work on putting something together.

dpwiz commented 7 years ago

A bare-bones example to get started (coding from memory, may require minor fixes...):

import Control.Distributed.Process (Process, ProcessId, getSelfPid, say, expect, send)
import Control.Distributed.Process.Node (newLocalNode, initRemoteTable)
import Network.Transport.TCP (createTransport, defaultTCPParameters)

main :: IO ()
main = do
  Right transport <- createTransport "*" "9876" defaultTCPParameters
  node <- newLocalNode transport initRemoteTable

  helloPid <- forkProcess node $ do
    replyTo <- expect :: Process ProcessId
    send replyTo ("hi there!" :: Text)

  spockCfg <- defaultSpockCfg () PCNoDatabase node
  runSpock 8080 . spock spockCfg $ do
    get root $ do
      node <- getState
      pid <- liftIO . forkProcess node $ do
        say "wow, i'm a process!" :: Process ()
        send helloPid =<< getSelfPid
        reply <- expect :: Process Text
        say $ show reply
      text $ "Spawned a process: " <> T.pack (show pid)

From there you can add your combinators and wrappers to shuttle data between web and node threads. Bring in websockets for extra fun.

brezal commented 7 years ago

I think that's a good enough example to get me started. Thanks @wiz