From 9c79dcc97a4fe36d2d859dfe31f1e7a7010d6ab8 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Sun, 24 Dec 2017 01:22:44 +0200 Subject: [PATCH] add locks on the MemoryService of the vue mvc example, keep it simple but runnable:P Former-commit-id: 5d661f401e486a26d66f5c0c297f5cf897fc1834 --- .../vuejs-todo-mvc/src/todo/service.go | 21 +++++++++++++++--- .../src/web/controllers/todo_controller.go | 2 +- .../tutorial/vuejs-todo-mvc/src/web/main.go | 22 ++++++++++++------- .../vuejs-todo-mvc/src/web/public/js/app.js | 3 +-- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/_examples/tutorial/vuejs-todo-mvc/src/todo/service.go b/_examples/tutorial/vuejs-todo-mvc/src/todo/service.go index 50f3df03..d9af2854 100644 --- a/_examples/tutorial/vuejs-todo-mvc/src/todo/service.go +++ b/_examples/tutorial/vuejs-todo-mvc/src/todo/service.go @@ -1,20 +1,33 @@ package todo +import ( + "sync" +) + type Service interface { Get(owner string) []Item Save(owner string, newItems []Item) error } type MemoryService struct { + // key = session id, value the list of todo items that this session id has. items map[string][]Item + // protected by locker for concurrent access. + mu sync.RWMutex } func NewMemoryService() *MemoryService { - return &MemoryService{make(map[string][]Item, 0)} + return &MemoryService{ + items: make(map[string][]Item, 0), + } } -func (s *MemoryService) Get(sessionOwner string) (items []Item) { - return s.items[sessionOwner] +func (s *MemoryService) Get(sessionOwner string) []Item { + s.mu.RLock() + items := s.items[sessionOwner] + s.mu.RUnlock() + + return items } func (s *MemoryService) Save(sessionOwner string, newItems []Item) error { @@ -26,6 +39,8 @@ func (s *MemoryService) Save(sessionOwner string, newItems []Item) error { } } + s.mu.Lock() s.items[sessionOwner] = newItems + s.mu.Unlock() return nil } diff --git a/_examples/tutorial/vuejs-todo-mvc/src/web/controllers/todo_controller.go b/_examples/tutorial/vuejs-todo-mvc/src/web/controllers/todo_controller.go index 5688ed0a..79fa48d9 100644 --- a/_examples/tutorial/vuejs-todo-mvc/src/web/controllers/todo_controller.go +++ b/_examples/tutorial/vuejs-todo-mvc/src/web/controllers/todo_controller.go @@ -54,7 +54,7 @@ func (c *TodoController) Post(newItems []todo.Item) PostItemResponse { func (c *TodoController) GetSync(conn websocket.Connection) { conn.Join(c.Session.ID()) conn.On("save", func() { // "save" event from client. - conn.To(c.Session.ID()).Emit("saved", nil) // fire a "save" event to the rest of the clients. + conn.To(c.Session.ID()).Emit("saved", nil) // fire a "saved" event to the rest of the clients w. }) conn.Wait() diff --git a/_examples/tutorial/vuejs-todo-mvc/src/web/main.go b/_examples/tutorial/vuejs-todo-mvc/src/web/main.go index 0136edfa..d125440c 100644 --- a/_examples/tutorial/vuejs-todo-mvc/src/web/main.go +++ b/_examples/tutorial/vuejs-todo-mvc/src/web/main.go @@ -21,28 +21,34 @@ func main() { // back-end services, you can just stop afer this line and start the server. app.StaticWeb("/", "./public") + // configure the http sessions. sess := sessions.New(sessions.Config{ Cookie: "iris_session", }) + // configure the websocket server. ws := websocket.New(websocket.Config{}) + // create a sub router and register the client-side library for the iris websockets, + // you could skip it but iris websockets supports socket.io-like API. + todosRouter := app.Party("/todos") + // http://localhost:8080/todos/iris-ws.js + // serve the javascript client library to communicate with + // the iris high level websocket event system. + todosRouter.Any("/iris-ws.js", websocket.ClientHandler()) + // create our mvc application targeted to /todos relative sub path. - m := mvc.New(app.Party("/todos")) + todosApp := mvc.New(todosRouter) + // any dependencies bindings here... - m.AddDependencies( + todosApp.AddDependencies( todo.NewMemoryService(), mvc.Session(sess), ws.Upgrade, ) - // http://localhost:8080/iris-ws.js - // serve the javascript client library to communicate with - // the iris high level websocket event system. - m.Router.Any("/iris-ws.js", websocket.ClientHandler()) - // controllers registration here... - m.Register(new(controllers.TodoController)) + todosApp.Register(new(controllers.TodoController)) // start the web server at http://localhost:8080 app.Run(iris.Addr(":8080"), iris.WithoutVersionChecker) diff --git a/_examples/tutorial/vuejs-todo-mvc/src/web/public/js/app.js b/_examples/tutorial/vuejs-todo-mvc/src/web/public/js/app.js index d843a78f..92135237 100644 --- a/_examples/tutorial/vuejs-todo-mvc/src/web/public/js/app.js +++ b/_examples/tutorial/vuejs-todo-mvc/src/web/public/js/app.js @@ -13,7 +13,7 @@ socket.On("saved", function () { function fetchTodos(onComplete) { axios.get("/todos").then(response => { - if (response.data == null) { + if (response.data === null) { return; } @@ -65,7 +65,6 @@ var app = new Vue({ // app initial state data: { todos: todoStorage.fetch(), - hasChanges: false, newTodo: '', editedTodo: null, visibility: 'all'