-
Notifications
You must be signed in to change notification settings - Fork 0
/
delivery.go
148 lines (121 loc) · 3.04 KB
/
delivery.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
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"log"
"os"
"time"
"encoding/json"
"strings"
"gopkg.in/redis.v3"
)
type (
//Request - Struct to hold the incoming request data
Request struct {
Method string `json:"method"`
URL string `json:"url"`
Data []RequestData `json:"data"`
}
RequestData struct {
Mascot string `json:"mascot"`
Location string `json:"location"`
Bar string `json:"bar"`
}
)
var ticker *time.Ticker
func main() {
client, err := createClient("localhost:1985", "evenkingscry!", 0)
if err != nil {
panicAndExit(err)
}
file := getLogFile("requests.log")
logger := log.New(file, "", log.Ltime)
ticker = time.NewTicker(time.Second)
go func() {
for range ticker.C {
keys, err := client.Keys("*").Result()
if err != nil {
panicAndExit(err)
}
go processData(client, logger, keys)
}
}()
//keeps the program running indefinitely
for {
}
}
/*
Process all request data stored in redis, and delete the processed keys from redis.
@param client: The redis client
@param logger: The logger for writing response to output file.
@param []keys: A slice of all keys in redis.
*/
func processData(client *redis.Client, logger *log.Logger, keys []string) {
for _, key := range keys {
value, err := client.Get(key).Result()
if err != nil {
logger.Printf("Failure on key: %s. %v\n", key, err)
continue
}
_, err = client.Del(key).Result()
if err != nil {
panicAndExit(err)
}
request := Request{}
err = json.Unmarshal([]byte(value), &request)
if err != nil {
panicAndExit(err)
}
processAndLogRequest(logger, request)
}
return
}
/*
processAndLogRequest: Process an individual request and logs the data to the "requests.log" file
@param request: Request data gotten from redis
@param logger: The logger for writing response to output file.
*/
func processAndLogRequest(logger *log.Logger, request Request) {
var mascot = "mascot"
var location = "location"
var bar = "bar"
for _, data := range request.Data {
url := request.URL
if len(data.Mascot) == 0 {
data.Mascot = mascot
}
if len(data.Location) == 0 {
data.Location = location
}
if len(data.Bar) == 0 {
data.Bar = bar
}
url = strings.Replace(url, "{mascot}", data.Mascot, 1)
url = strings.Replace(url, "{location}", data.Location, 1)
url = strings.Replace(url, "{bar}", data.Bar, 1)
logger.Printf("%s %s ", request.Method, url)
}
}
func getLogFile(fileName string) *os.File {
//read write access, create it it doesnt exist, append data
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panicAndExit(err)
}
return file
}
func createClient(address string, password string, dbNumber int64) (*redis.Client, error) {
client := redis.NewClient(&redis.Options{
Addr: address,
Password: password, // no password set
DB: dbNumber, // use default DB
})
_, err := client.Ping().Result()
if err != nil {
panicAndExit(err)
}
return client, nil
}
func panicAndExit(err error) {
log.Printf("%v\n", err)
ticker.Stop() //stop time ticker
os.Exit(-1)
}