1
0
mirror of https://github.com/bingohuang/docker-labs.git synced 2025-07-14 01:57:32 +08:00

Refactor sessions and add locking to avoid concurrent requests to create

more instances
This commit is contained in:
Marcos Lilljedahl 2016-10-14 12:54:25 -03:00
parent d19e8a0cd3
commit a56af3dc22
7 changed files with 21 additions and 26 deletions

4
api.go
View File

@ -18,7 +18,7 @@ func main() {
mux.Get("/", http.HandlerFunc(handlers.NewSession))
mux.Get("/sessions/:sessionId", http.HandlerFunc(handlers.GetSession))
mux.Post("/sessions/:sessionId/instances", http.HandlerFunc(handlers.NewInstance))
mux.Delete("/sessions/:sessionId/instances/:instanceId", http.HandlerFunc(handlers.DeleteInstance))
mux.Delete("/sessions/:sessionId/instances/:instanceName", http.HandlerFunc(handlers.DeleteInstance))
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./www/index.html")
@ -26,7 +26,7 @@ func main() {
mux.Get("/p/:sessionId", h)
mux.Get("/assets/*", http.FileServer(http.Dir("./www")))
mux.Get("/sessions/:sessionId/instances/:instanceId/attach", websocket.Handler(handlers.Exec))
mux.Get("/sessions/:sessionId/instances/:instanceName/attach", websocket.Handler(handlers.Exec))
n := negroni.Classic()
n.UseHandler(mux)

View File

@ -9,10 +9,10 @@ import (
func DeleteInstance(rw http.ResponseWriter, req *http.Request) {
sessionId := bone.GetValue(req, "sessionId")
instanceId := bone.GetValue(req, "instanceId")
instanceName := bone.GetValue(req, "instanceName")
s := services.GetSession(sessionId)
i := services.GetInstance(s, instanceId)
i := services.GetInstance(s, instanceName)
err := services.DeleteInstance(s, i)
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)

View File

@ -15,12 +15,12 @@ import (
// Echo the data received on the WebSocket.
func Exec(ws *websocket.Conn) {
sessionId := bone.GetValue(ws.Request(), "sessionId")
instanceId := bone.GetValue(ws.Request(), "instanceId")
instanceName := bone.GetValue(ws.Request(), "instanceName")
ctx := context.Background()
session := services.GetSession(sessionId)
instance := services.GetInstance(session, instanceId)
instance := services.GetInstance(session, instanceName)
if instance.Stdout == nil {
id, err := services.CreateExecConnection(instance.Name, ctx)

View File

@ -14,12 +14,14 @@ func NewInstance(rw http.ResponseWriter, req *http.Request) {
s := services.GetSession(sessionId)
s.Lock()
if len(s.Instances) >= 5 {
rw.WriteHeader(http.StatusConflict)
return
}
i, err := services.NewInstance(s)
s.Unlock()
if err != nil {
log.Println(err)
//TODO: Set a status error

View File

@ -7,20 +7,17 @@ import (
"github.com/franela/play-with-docker/types"
)
var instances map[string]map[string]*types.Instance
var dindImage string
var defaultDindImageName string
func init() {
instances = make(map[string]map[string]*types.Instance)
dindImage = getDindImageName()
dindImage = getDindImageName()
}
func getDindImageName() string {
dindImage := os.Getenv("DIND_IMAGE")
defaultDindImageName = "docker:1.12.2-rc2-dind"
if len(dindImage) == 0 {
defaultDindImageName = "docker:1.12.2-rc2-dind"
if len(dindImage) == 0 {
dindImage = defaultDindImageName
}
return dindImage
@ -37,21 +34,20 @@ func NewInstance(session *types.Session) (*types.Instance, error) {
return nil, err
}
if instances[session.Id] == nil {
instances[session.Id] = make(map[string]*types.Instance)
if session.Instances == nil {
session.Instances = make(map[string]*types.Instance)
}
instances[session.Id][instance.Name] = instance
session.Instances[instance.Name] = instance
return instance, nil
}
func GetInstance(session *types.Session, instanceId string) *types.Instance {
func GetInstance(session *types.Session, name string) *types.Instance {
//TODO: Use redis
i := instances[session.Id][instanceId]
return i
return session.Instances[name]
}
func DeleteInstance(session *types.Session, instance *types.Instance) error {
//TODO: Use redis
delete(instances[session.Id], instance.Name)
delete(session.Instances, instance.Name)
return DeleteContainer(instance.Name)
}

View File

@ -49,11 +49,5 @@ func NewSession() (*types.Session, error) {
func GetSession(sessionId string) *types.Session {
//TODO: Use redis
s, found := sessions[sessionId]
if found {
s.Instances = instances[sessionId]
return s
} else {
return nil
}
return sessions[sessionId]
}

View File

@ -1,11 +1,14 @@
package types
import (
"sync"
"github.com/docker/docker/api/types"
"github.com/franela/play-with-docker/cookoo"
)
type Session struct {
sync.Mutex
Id string `json:"id"`
Instances map[string]*Instance `json:"instances"`
}