Last active
December 23, 2015 11:00
-
-
Save chakrit/2e40dd624d940a8de722 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.so | |
*.h | |
main | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2.2.3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'ffi' | |
module GoMachine | |
extend FFI::Library | |
ffi_lib './gomachine.so' | |
attach_function :Start, [], :void | |
attach_function :Request, [:string], :uint64 | |
attach_function :Result, [:uint64], :string | |
end | |
MAGNITUDE = 50 | |
GoMachine.Start | |
(1..MAGNITUDE). | |
map { |n| GoMachine.Request("https://api.omise.co/ping") }. | |
map { |id| GoMachine.Result(id) }. | |
each do |result| | |
puts result | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "C" | |
import "fmt" | |
import "net/http" | |
import "sync/atomic" | |
import "io/ioutil" | |
var counter int32 | |
const ( | |
PortGet = iota * 1000 | |
PortSet | |
) | |
type Port chan string | |
type PortCommand struct { | |
Cmd int | |
ID int32 | |
Port Port | |
Result chan Port | |
} | |
type PortActor struct { | |
registry map[int32]Port | |
commands chan *PortCommand | |
} | |
func NewPortActor() *PortActor { | |
return &PortActor{ | |
map[int32]Port{}, | |
make(chan *PortCommand, 10), | |
} | |
} | |
func (a *PortActor) Start() { | |
go func() { | |
for cmd := range a.commands { | |
switch cmd.Cmd { | |
case PortGet: | |
cmd.Result <- a.registry[cmd.ID] | |
case PortSet: | |
a.registry[cmd.ID] = cmd.Port | |
default: | |
panic("actor received invalid command.") | |
} | |
} | |
}() | |
} | |
func (a *PortActor) Set(id int32, port Port) { | |
a.commands <- &PortCommand{PortSet, id, port, nil} | |
} | |
func (a *PortActor) Delete(id int32) Port { | |
result := make(chan Port) | |
a.commands <- &PortCommand{PortGet, id, nil, result} | |
return <-result | |
} | |
var actor *PortActor | |
//export Start | |
func Start() { | |
actor = NewPortActor() | |
actor.Start() | |
} | |
//export Request | |
func Request(rawurl *C.char) int32 { | |
url := C.GoString(rawurl) | |
// fmt.Println(url) | |
// return 0 | |
port := make(Port) | |
go func() { | |
// TODO: Don't ignore error | |
defer close(port) | |
response, err := http.Get(url) | |
if err != nil { | |
fmt.Println(err) | |
port <- err.Error() | |
return | |
} | |
if response.Body != nil { | |
defer response.Body.Close() | |
} | |
bytes, err := ioutil.ReadAll(response.Body) | |
port <- string(bytes) | |
_ = err | |
}() | |
id := atomic.AddInt32(&counter, 1) | |
actor.Set(id, port) | |
return id | |
} | |
//export Result | |
func Result(id int32) string { | |
return <-actor.Delete(id) | |
} | |
func main() {} // required, but ignored | |
// Test: | |
// | |
// func main() { | |
// resp, e := http.Get("https://api.omise.co/ping") | |
// if e != nil { | |
// panic(e) | |
// } | |
// bytes, e := ioutil.ReadAll(resp.Body) | |
// if e != nil { | |
// panic(e) | |
// } | |
// fmt.Println(string(bytes)) | |
// } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rm gomachine.so | |
go build -buildmode=c-shared -o gomachine.so main.go | |
ruby bridge.rb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
./test.sh 1.71s user 0.41s system 48% cpu 4.423 total