Skip to content

Instantly share code, notes, and snippets.

@jgrimes
Last active January 3, 2016 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgrimes/f5eba19b27bf997abf6d to your computer and use it in GitHub Desktop.
Save jgrimes/f5eba19b27bf997abf6d to your computer and use it in GitHub Desktop.
modified boot.go to run a script
package main
import (
"fmt"
"github.com/jackpal/bencode-go"
"net"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
)
type Request struct {
Op string "op"
Code string "code"
}
type Response struct {
Session string "session"
Out string "out"
Status []string "status"
Ex string "ex"
RootEx string "root-ex"
}
func NewRequest(taskargs []string) *Request {
code := "(boot"
if len(taskargs) > 0 {
for _, taskarg := range taskargs {
code += " " + strconv.Quote(taskarg)
}
} else {
code += " help"
}
code += ")"
return &Request{"eval", code}
}
type Server struct {
Conn net.Conn
}
func CreateServer(url string) (*Server, error) {
conn, err := net.Dial("tcp", url)
if err != nil {
return nil, err
}
return &Server{conn}, nil
}
func (srv Server) send(req *Request) (*Response, error) {
if err := bencode.Marshal(srv.Conn, *req); err != nil {
return nil, err
}
res := &Response{}
if err := bencode.Unmarshal(srv.Conn, res); err != nil {
return nil, err
}
return res, nil
}
func (srv Server) execScript(path string, args []string) (*Response, error) {
res, err := srv.send(&Request{"eval",
fmt.Sprintf(`
(def script-path "%s")
(def pod (pool-service))
#_(def out (p/with-eval-in pod
(do
(load-file "%s")
(with-out-str (-main))
)))
#_(println out)
(load-file script-path)
(print (with-out-str (-main %s)))
`, path, path, strings.Join(args, " "))})
return res, err
}
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
func main() {
var wg sync.WaitGroup
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
fullpath := filepath.Join(dir, os.Args[1])
args := os.Args[2:]
srv, err := CreateServer("0.0.0.0:52644")
if err != nil {
fmt.Fprintf(os.Stderr, "Error connecting to boot server: %v\n", err)
os.Exit(1)
}
wg.Add(1)
go func(wg *sync.WaitGroup, srv *Server) {
for {
res := &Response{}
bencode.Unmarshal(srv.Conn, res)
// Note: I was seeing some weird behavior with nrepl
// where it would sometimes be done executing but not
// return a "done" status
if stringInSlice("done", res.Status) || res.Out != "" {
fmt.Fprintf(os.Stdout, "%v", res.Out)
wg.Done()
return
}
if stringInSlice("eval-error", res.Status) {
fmt.Fprintf(os.Stdout, "Exception: %v\n", res.Ex)
wg.Done()
return
}
}
}(&wg, srv)
res, err := srv.execScript(fullpath, args)
if err != nil {
fmt.Fprintf(os.Stderr, "Error encoding or decoding tasks: %v\n", err)
os.Exit(1)
} else if res.Ex != "" {
fmt.Fprintf(os.Stderr, "Error from boot build server: %v\n", res.Ex)
os.Exit(1)
}
wg.Wait()
}
#!/usr/bin/env boot-srv
(set-env! :dependencies '[[org.clojure/math.numeric-tower "0.0.4"]])
(require '[clojure.math.numeric-tower :refer [floor ceil round]])
(defn -main [& args]
(println "args: " args)
(if-let [arg (first args)]
(println (floor (first args))))
(println "yay"))
;; ./test.clj 4.2 3.3 2.0
;; time (for i in $(seq 1 100); do (./test.clj 4.2 3.3 $i) ; done)
;; ( for i in $(seq 1 100); do; ( ./test.clj 4.2 3.3 $i; ); done; ) 0.21s user 0.33s system 25% cpu 2.099 total
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment