moved javaRuntime to Unison.Codebase.Runtime.JVM module

This commit is contained in:
Arya Irani 2018-10-17 15:09:37 -04:00
parent 282e53cad8
commit ff8f9b19e4
5 changed files with 88 additions and 80 deletions

View File

@ -33,6 +33,7 @@ main dir currentBranchName codebase = do
queue <- TQueue.newIO queue <- TQueue.newIO
lineQueue <- TQueue.newIO lineQueue <- TQueue.newIO
branchFileChanges <- TQueue.newIO branchFileChanges <- TQueue.newIO
-- enqueue stdin into lineQueue -- enqueue stdin into lineQueue
void . forkIO . forever $ getChar >>= atomically . TQueue.enqueue lineQueue void . forkIO . forever $ getChar >>= atomically . TQueue.enqueue lineQueue

View File

@ -0,0 +1,53 @@
module Unison.Codebase.Runtime.JVM where
import Control.Applicative
import Control.Monad.State (evalStateT)
import Data.Bytes.Put (runPutS)
import Data.ByteString (ByteString)
import Network.Socket
import System.IO.Streams (InputStream, OutputStream)
import qualified System.IO.Streams as Streams
import qualified System.IO.Streams.Network as N
import qualified System.Process as P
import Unison.Codebase.Runtime (Runtime (..))
import qualified Unison.Codebase.Runtime as RT
import qualified Unison.Codecs as Codecs
import Unison.Var (Var)
javaRuntime :: Var v => Int -> IO (Runtime v)
javaRuntime suggestedPort = do
(listeningSocket, port) <- choosePortAndListen suggestedPort
(killme, input, output) <- connectToRuntime listeningSocket port
pure $ Runtime killme (feedme input output)
where
feedme :: Var v
=> InputStream ByteString -> OutputStream ByteString
-> RT.UnisonFile v -> RT.Codebase v -> IO ()
feedme _input output unisonFile _codebase = do
-- todo: runtime should be able to request more terms/types/arities by hash
let bs = runPutS $ flip evalStateT 0 $ Codecs.serializeFile unisonFile
Streams.write (Just bs) output
-- open a listening socket for the runtime to connect to
choosePortAndListen :: Int -> IO (Socket, Int)
choosePortAndListen suggestedPort = do
sock <- socket AF_INET Stream 0
setSocketOption sock ReuseAddr 1
let bindLoop port =
(port <$ bind sock (SockAddrInet (fromIntegral port) iNADDR_ANY))
<|> bindLoop (port + 1) -- try the next port if that fails
chosenPort <- bindLoop suggestedPort
listen sock 2
pure (sock, chosenPort)
-- start the runtime and wait for it to connect to us
connectToRuntime ::
Socket -> Int -> IO (IO (), InputStream ByteString, OutputStream ByteString)
connectToRuntime listenSock port = do
let cmd = "scala"
args = ["-cp", "runtime-jvm/main/target/scala-2.12/classes",
"org.unisonweb.BootstrapStream", show port]
(_,_,_,ph) <- P.createProcess (P.proc cmd args) { P.cwd = Just "." }
(socket, _address) <- accept listenSock -- accept a connection and handle it
(input, output) <- N.socketToStreams socket
pure (P.terminateProcess ph, input, output)

View File

@ -1,88 +1,40 @@
{-# LANGUAGE DoAndIfThenElse #-} {-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE OverloadedStrings #-} -- for FilePath literals {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeApplications #-}
module Unison.Codebase.Watch where module Unison.Codebase.Watch where
import System.Directory (canonicalizePath) import Control.Concurrent (forkIO, threadDelay)
import qualified System.Console.ANSI as Console
import Data.IORef
import Data.Time.Clock (UTCTime, diffUTCTime)
import Control.Concurrent (threadDelay, forkIO)
import Control.Concurrent.MVar import Control.Concurrent.MVar
import Control.Concurrent.STM (atomically) import Control.Concurrent.STM (atomically)
import Control.Monad (forever, void) import Control.Monad (forever, void)
import System.FSNotify (Event(Added,Modified),withManager,watchTree) import Data.Foldable (toList)
import Network.Socket import Data.IORef
import Control.Applicative import Data.List (isSuffixOf)
import qualified System.IO.Streams.Network as N import qualified Data.Map as Map
import Data.Foldable (toList) import Data.Text (Text)
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.IO import qualified Data.Text.IO
import qualified Data.Map as Map import Data.Time.Clock (UTCTime, diffUTCTime)
import Data.List (isSuffixOf) import qualified System.Console.ANSI as Console
import Data.Text (Text) import System.Directory (canonicalizePath)
import qualified Unison.FileParsers as FileParsers import System.FSNotify (Event (Added, Modified), watchTree,
import qualified Unison.Parser as Parser withManager)
import qualified Unison.Parsers as Parsers import qualified Unison.FileParsers as FileParsers
import qualified Unison.Parser as Parser
import qualified Unison.Parsers as Parsers
-- import Unison.Util.AnnotatedText (renderTextUnstyled) -- import Unison.Util.AnnotatedText (renderTextUnstyled)
import Unison.PrintError (parseErrorToAnsiString, printNoteWithSourceAsAnsi) -- , renderType') import Control.Exception (finally)
import Unison.Result (Result (Result)) import System.Random (randomIO)
import Unison.Util.Monoid import Unison.Codebase.Runtime (Runtime (..))
import Unison.Util.TQueue (TQueue)
import qualified Unison.Util.TQueue as TQueue
import qualified System.IO.Streams as Streams
import System.IO.Streams (InputStream, OutputStream)
import qualified System.Process as P
import System.Random (randomIO)
import Control.Exception (finally)
import Data.ByteString (ByteString)
import Unison.Var (Var)
import Unison.Codebase.Runtime (Runtime(..))
import qualified Unison.Codebase.Runtime as RT import qualified Unison.Codebase.Runtime as RT
import qualified Unison.Codecs as Codecs import Unison.PrintError (parseErrorToAnsiString,
import Data.Bytes.Put (runPutS) printNoteWithSourceAsAnsi)
import Control.Monad.State (evalStateT) import Unison.Result (Result (Result))
import Unison.Util.Monoid
javaRuntime :: Var v => Int -> IO (Runtime v) import Unison.Util.TQueue (TQueue)
javaRuntime suggestedPort = do import qualified Unison.Util.TQueue as TQueue
(listeningSocket, port) <- choosePortAndListen suggestedPort import Unison.Var (Var)
(killme, input, output) <- connectToRuntime listeningSocket port
pure $ Runtime killme (feedme input output)
where
feedme :: Var v
=> InputStream ByteString -> OutputStream ByteString
-> RT.UnisonFile v -> RT.Codebase v -> IO ()
feedme _input output unisonFile _codebase = do
-- todo: runtime should be able to request more terms/types/arities by hash
let bs = runPutS $ flip evalStateT 0 $ Codecs.serializeFile unisonFile
Streams.write (Just bs) output
-- open a listening socket for the runtime to connect to
choosePortAndListen :: Int -> IO (Socket, Int)
choosePortAndListen suggestedPort = do
sock <- socket AF_INET Stream 0
setSocketOption sock ReuseAddr 1
let bindLoop port =
(port <$ bind sock (SockAddrInet (fromIntegral port) iNADDR_ANY))
<|> bindLoop (port + 1) -- try the next port if that fails
chosenPort <- bindLoop suggestedPort
listen sock 2
pure (sock, chosenPort)
-- start the runtime and wait for it to connect to us
connectToRuntime ::
Socket -> Int -> IO (IO (), InputStream ByteString, OutputStream ByteString)
connectToRuntime listenSock port = do
let cmd = "scala"
args = ["-cp", "runtime-jvm/main/target/scala-2.12/classes",
"org.unisonweb.BootstrapStream", show port]
(_,_,_,ph) <- P.createProcess (P.proc cmd args) { P.cwd = Just "." }
(socket, _address) <- accept listenSock -- accept a connection and handle it
(input, output) <- N.socketToStreams socket
pure (P.terminateProcess ph, input, output)
watchDirectory' :: FilePath -> IO (IO (FilePath, UTCTime)) watchDirectory' :: FilePath -> IO (IO (FilePath, UTCTime))
watchDirectory' d = do watchDirectory' d = do
@ -91,9 +43,9 @@ watchDirectory' d = do
_ <- tryTakeMVar mvar _ <- tryTakeMVar mvar
putMVar mvar (fp, t) putMVar mvar (fp, t)
handler e = case e of handler e = case e of
Added fp t False -> doIt fp t Added fp t False -> doIt fp t
Modified fp t False -> doIt fp t Modified fp t False -> doIt fp t
_ -> pure () _ -> pure ()
_ <- forkIO $ withManager $ \mgr -> do _ <- forkIO $ withManager $ \mgr -> do
_ <- watchTree mgr d (const True) handler _ <- watchTree mgr d (const True) handler
forever $ threadDelay 1000000 forever $ threadDelay 1000000

View File

@ -45,6 +45,7 @@ library
Unison.Codebase.Name Unison.Codebase.Name
Unison.Codebase.NameEdit Unison.Codebase.NameEdit
Unison.Codebase.Runtime Unison.Codebase.Runtime
Unison.Codebase.Runtime.JVM
Unison.Codebase.TermEdit Unison.Codebase.TermEdit
Unison.Codebase.TypeEdit Unison.Codebase.TypeEdit
Unison.Codebase.Serialization Unison.Codebase.Serialization

View File

@ -6,11 +6,12 @@ import System.Environment (getArgs)
-- import qualified Unison.Codebase as Codebase -- import qualified Unison.Codebase as Codebase
import qualified Unison.Codebase.Watch as W import qualified Unison.Codebase.Watch as W
import Unison.Symbol (Symbol) import Unison.Symbol (Symbol)
import Unison.Codebase.Runtime.JVM (javaRuntime)
main :: IO () main :: IO ()
main = do main = do
args <- getArgs args <- getArgs
runtime <- W.javaRuntime @Symbol 42441 runtime <- javaRuntime @Symbol 42441
case args of case args of
[""] -> go runtime Nothing [""] -> go runtime Nothing
_ -> go runtime (headMay args) _ -> go runtime (headMay args)