mirror of
https://github.com/bingohuang/docker-labs.git
synced 2025-07-14 10:17:26 +08:00
Refactor sessions and add locking to avoid concurrent requests to create
more instances
This commit is contained in:
parent
d19e8a0cd3
commit
a56af3dc22
4
api.go
4
api.go
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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"`
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user