-
Notifications
You must be signed in to change notification settings - Fork 0
/
keymaker.go
136 lines (109 loc) · 3.31 KB
/
keymaker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"github.com/sheng/air"
"github.com/astaxie/beego/orm"
_ "github.com/mattn/go-sqlite3"
"github.com/kamildrazkiewicz/go-flow"
"math/rand"
"time"
"strconv"
"fmt"
)
// Model Struct
type Key struct {
Id int `orm:"auto"`
Value string `orm:"size(256)"`
Status string `orm:"size(10)"`
}
var o orm.Ormer
func init() {
// register model
orm.RegisterModel(new(Key))
name := "default"
maxIdle := 30
maxConn := 30
// set default database
orm.RegisterDataBase(name, "sqlite3", "data.db", maxIdle, maxConn)
force := true
verbose := true
orm.RunSyncdb(name, force, verbose)
}
func main() {
a := air.New()
a.GET("/v1/get", keyGetter)
a.GET("/v1/validate/:id", keyValidate)
o = orm.NewOrm()
test_key := Key{Value: "test", Status: "test"}
o.Insert(&test_key)
a.Serve()
}
func keyGetter(c *air.Context) error {
keyLength := 64
value := RandStringBytesMaskImprSrc(keyLength)
key := Key{Value: value, Status: "active"}
go newKeyWorker(key)
return c.String(value)
}
func keyValidate(c *air.Context) error {
qs := o.QueryTable("key")
var key Key
qs.Filter("value", c.Param("id")).Filter("status", "active").One(&key)
result := strconv.FormatBool(key.Value == c.Param("id"))
return c.String(result)
}
// Hash function from http://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang/31832326
var src = rand.NewSource(time.Now().UnixNano())
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789"
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
func RandStringBytesMaskImprSrc(n int) string {
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
func newKeyWorker(k Key) {
active := func(r map[string]interface{}) (interface{}, error) {
time.Sleep(time.Millisecond * 500)
fmt.Println("active started", "---", k.Value)
o.Insert(&k)
fmt.Println("active finished", "---", k.Value)
return nil, nil
}
inactive := func(r map[string]interface{}) (interface{}, error) {
time.Sleep(time.Millisecond * 30000)
fmt.Println("inactive started", "---", k.Value)
qs := o.QueryTable("key")
var key Key
qs.Filter("id", k.Id).One(&key)
key.Status = "inactive"
o.Update(&key, "Status")
fmt.Println("inactive finished", "---", k.Value)
return nil, nil
}
killed := func(r map[string]interface{}) (interface{}, error) {
time.Sleep(time.Millisecond * 60000)
fmt.Println("killed started", "---", k.Value)
o.Delete(&Key{Id: k.Id})
fmt.Println("killed finished", "---", k.Value)
return nil, nil
}
goflow.New().
Add("active", nil, active).
Add("inactive", nil, inactive).
Add("killed", nil, killed).
Do()
}