Permalink
Browse files

Merge pull request #3 from sorah/isuroxy

Implemented proxy
  • Loading branch information...
rosylilly committed Oct 22, 2017
2 parents 2681545 + 2e11577 commit e2d5352794a1a7614518136089abf6c634db0c07
View
@@ -0,0 +1,3 @@
bin
pkg
src/github.com
View
@@ -0,0 +1,11 @@
GOPATH := ${PWD}
export GOPATH
build: bin/isuroxy
dependency: deps
@cat deps | xargs -n 1 go get -v
bin/isuroxy: dependency src/**/*.go
@mkdir -p bin
go build -o bin/isuroxy -v isuroxy
View
@@ -0,0 +1,9 @@
#!/bin/bash -ex
cd ~/isubata/proxy
make build
sudo cp isubata.proxy.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl restart isubata.proxy
View
@@ -0,0 +1 @@
github.com/go-redis/redis
@@ -0,0 +1,22 @@
[Unit]
Description = isucon7 qualifier proxy application for fetch
[Service]
WorkingDirectory=/home/isucon/isubata/proxy
EnvironmentFile=/home/isucon/env.sh
Environment=RACK_ENV=production
ExecStart = /home/isucon/isubata/proxy/bin/isuroxy
Restart = always
Type = simple
User = isucon
Group = isucon
RuntimeDirectory=isubata
LimitNOFILE=16384
LimitNOFILESoft=16384
[Install]
WantedBy = multi-user.target
@@ -0,0 +1,31 @@
package main
import (
"os"
"strconv"
"time"
)
func main() {
backend := os.Getenv("ISUROXY_BACKEND")
if len(backend) == 0 {
backend = "localhost:5000"
}
timeout := os.Getenv("ISUROXY_TIMEOUT")
if len(timeout) == 0 {
timeout = "5"
}
ts, err := strconv.Atoi(timeout)
if ts == 0 || err != nil {
ts = 5
}
s := &Server{
Backend: backend,
Timeout: time.Duration(ts) * time.Second,
}
s.Start()
}
@@ -0,0 +1,104 @@
package main
import (
"github.com/go-redis/redis"
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
"time"
)
const STREAM_KEY = "isubata:stream:message"
type receiver chan struct{}
type Server struct {
redis *redis.Client
receivers chan receiver
Backend string
Timeout time.Duration
}
func (s *Server) Wait() {
rec := make(receiver, 1)
s.receivers <- rec
select {
case <-rec:
return
case <-time.After(s.Timeout):
return
}
}
func (s *Server) Director(request *http.Request) {
s.Wait()
request.URL.Scheme = "http"
request.URL.Host = s.Backend
}
func (s *Server) initRedis() {
redisURL := os.Getenv("ISUBATA_REDIS_URL")
if len(redisURL) == 0 {
redisURL = "redis://localhost:6379/0"
}
u, err := url.Parse(redisURL)
if err != nil {
log.Println("Can't parse redis URL. Check your ISUBATA_REDIS_URL")
log.Fatal(err.Error())
}
s.redis = redis.NewClient(&redis.Options{
Addr: u.Host,
DB: 0, // use default DB
})
_, err = s.redis.Ping().Result()
if err != nil {
log.Println("Can't connect to redis. Check your ISUBATA_REDIS_URL")
log.Fatal(err.Error())
}
go func() {
for {
pubsub := s.redis.Subscribe(STREAM_KEY)
for {
_, err := pubsub.ReceiveMessage()
if err != nil {
log.Println("PubSub error")
log.Fatal(err.Error())
break
}
for rec := range s.receivers {
rec <- struct{}{}
}
}
}
}()
}
func (s *Server) Start() {
s.receivers = make(chan receiver, 1000)
s.initRedis()
rp := &httputil.ReverseProxy{Director: s.Director}
server := http.Server{
Addr: ":9000",
Handler: rp,
}
server.SetKeepAlivesEnabled(true)
log.Println("=== Started ===")
log.Printf("Backend: %s / Timeout: %s", s.Backend, s.Timeout)
if err := server.ListenAndServe(); err != nil {
log.Fatal(err.Error())
}
}

0 comments on commit e2d5352

Please sign in to comment.