Commit b9df27c0 by lancet

working proof-of-concept

parent ff5f12b0
No preview for this file type
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
func main() { func main() {
router := new(web.Svc) router := new(web.Svc)
storage := new(vault.Store) storage := new(vault.Store)
storage.Init(30) storage.Init(10)
routing := []web.Route{ routing := []web.Route{
{URL: "/storage/{id}", Methods: []string{"GET"}, Handler: router.GetValue}, {URL: "/storage/{id}", Methods: []string{"GET"}, Handler: router.GetValue},
{URL: "/storage/{id}/{value}", Methods: []string{"PUT", "POST"}, Handler: router.SetValue}, {URL: "/storage/{id}/{value}", Methods: []string{"PUT", "POST"}, Handler: router.SetValue},
......
...@@ -27,6 +27,7 @@ func (store *Store) Init(ttl uint64) error { ...@@ -27,6 +27,7 @@ func (store *Store) Init(ttl uint64) error {
return nil return nil
} }
// cleaner - уничтожаем устаревшие ключи
func (store *Store) cleaner() { func (store *Store) cleaner() {
reply := make(chan Message) reply := make(chan Message)
for { for {
......
package vault package vault
import "errors" import (
"errors"
)
// addNode - добавляем новый узел в хвост очереди. // addNode - добавляем новый узел в хвост очереди.
func (store *Store) addNode(key, value string, kind bool) { func (store *Store) addNode(key, value string, kind bool) {
...@@ -9,6 +11,9 @@ func (store *Store) addNode(key, value string, kind bool) { ...@@ -9,6 +11,9 @@ func (store *Store) addNode(key, value string, kind bool) {
prev = store.tail prev = store.tail
} }
store.tail = &node{Key: key, Value: value, Prev: prev, Kind: kind} store.tail = &node{Key: key, Value: value, Prev: prev, Kind: kind}
if store.head == nil {
store.head = store.tail
}
if prev != nil { if prev != nil {
prev.Next = store.tail prev.Next = store.tail
} }
...@@ -25,26 +30,8 @@ func (store *Store) setNode(key, value string) error { ...@@ -25,26 +30,8 @@ func (store *Store) setNode(key, value string) error {
store.addNode(key, value, true) store.addNode(key, value, true)
return nil return nil
} }
// Вместо того, чтобы удалить и пересоздать, просто правим ссылки. store.delNode(key) // Сильно нерационально, удаление/создание объекта
// Так будет эффективней, чем удалять и создавать объекты данных. store.addNode(key, value, true) // Зато резко упрощает код
node := store.flat[key]
head := store.head
prev := node.Prev
next := node.Next
if prev != nil {
prev.Next = next
}
if next != nil {
next.Prev = prev
}
if store.head == node {
store.head = prev
}
if store.tail == node {
store.tail = next
}
store.head = node
node.Next = head
return nil return nil
} }
...@@ -52,16 +39,21 @@ func (store *Store) setNode(key, value string) error { ...@@ -52,16 +39,21 @@ func (store *Store) setNode(key, value string) error {
// Если Kind == 0 - то возвращаем ошибку. // Если Kind == 0 - то возвращаем ошибку.
// При ошибке устаревание приостанавливается на секунду. // При ошибке устаревание приостанавливается на секунду.
func (store *Store) popNode() error { func (store *Store) popNode() error {
var err error
if store.head == nil { if store.head == nil {
return errors.New("No nodes") return errors.New("No nodes")
} }
if store.head.Kind == false { if store.head.Kind == false {
return errors.New("Decay timeout") err = errors.New("Decay timeout")
} }
key := store.head.Key if store.head.Key != "" {
delete(store.flat, key) delete(store.flat, store.head.Key)
store.head = store.head.Next }
return nil if store.head.Next != nil {
store.head = store.head.Next
store.head.Prev = nil
}
return err
} }
// getNode - получить значение ключа, или ошибку, если такого нет. // getNode - получить значение ключа, или ошибку, если такого нет.
......
...@@ -13,16 +13,33 @@ import ( ...@@ -13,16 +13,33 @@ import (
func (svc *Svc) GetValue(w http.ResponseWriter, r *http.Request) { func (svc *Svc) GetValue(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
id := vars["id"] id := vars["id"]
resp := fmt.Sprintf("Get ID: %s\n", id) reply := make(chan vault.Message)
fmt.Fprint(w, resp) msg := vault.Message{Action: "GET", Reply: reply, Key: id}
svc.exchange <- msg
resp := <-reply
if resp.Error != true {
fmt.Fprint(w, resp.Value)
return
}
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "FAILURE")
} }
// SetValue - установить/обновить значение ключа // SetValue - установить/обновить значение ключа
func (svc *Svc) SetValue(w http.ResponseWriter, r *http.Request) { func (svc *Svc) SetValue(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
id := vars["id"] id := vars["id"]
resp := fmt.Sprintf("Set ID: %s\n", id) v := vars["value"]
fmt.Fprint(w, resp) reply := make(chan vault.Message)
msg := vault.Message{Action: "SET", Reply: reply, Key: id, Value: v}
svc.exchange <- msg
resp := <-reply
if resp.Error != true {
fmt.Fprint(w, "OK")
return
}
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, "FAILURE")
} }
// DelValue - удалить ключ из хранилища // DelValue - удалить ключ из хранилища
...@@ -44,7 +61,7 @@ func (svc *Svc) InitRouter(routes []Route, exch chan vault.Message) { ...@@ -44,7 +61,7 @@ func (svc *Svc) InitRouter(routes []Route, exch chan vault.Message) {
svc.router.HandleFunc(i.URL, i.Handler).Methods(j) svc.router.HandleFunc(i.URL, i.Handler).Methods(j)
} }
} }
svc.Exchange = exch svc.exchange = exch
return return
} }
......
...@@ -16,6 +16,6 @@ type Route struct { ...@@ -16,6 +16,6 @@ type Route struct {
// Svc - обмен данными с хранилищем // Svc - обмен данными с хранилищем
type Svc struct { type Svc struct {
Exchange chan vault.Message exchange chan vault.Message
router *mux.Router router *mux.Router
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment