1
1
package handlers
2
2
3
3
import (
4
- "context"
5
4
"encoding/json"
6
5
"errors"
7
6
"fmt"
@@ -10,17 +9,14 @@ import (
10
9
"time"
11
10
12
11
"github.com/aws/aws-sdk-go/aws"
12
+ "github.com/aws/aws-sdk-go/service/sqs"
13
13
"github.com/golang/glog"
14
- mq "github.com/remind101/mq-go"
15
14
)
16
15
17
- const MAX_RETRIES = 3
18
-
19
16
type SQSHandler struct {
20
17
QueueURL string
21
18
Start bool
22
19
JobConfigs []JobConfig
23
- Server * mq.Server
24
20
MonitoredJobs []* JobInfo
25
21
Mu sync.Mutex
26
22
}
@@ -49,27 +45,84 @@ func NewSQSHandler(queueURL string) *SQSHandler {
49
45
50
46
// StartServer starts a server
51
47
func (handler * SQSHandler ) StartServer () error {
52
- // return nil if the server already start
53
- if handler .Server != nil {
54
- return nil
55
- }
56
48
49
+ glog .Info ("Starting a new server ..." )
50
+
51
+ go handler .StartConsumingProcess ()
52
+ go handler .StartMonitoringProcess ()
53
+ go handler .RemoveCompletedJobsProcess ()
54
+
55
+ glog .Info ("The server is started" )
56
+
57
+ return nil
58
+
59
+ }
60
+
61
+ // StartConsumingProcess starts consumming the queue
62
+ func (handler * SQSHandler ) StartConsumingProcess () error {
57
63
newClient , err := NewSQSClient ()
58
64
if err != nil {
59
65
return err
60
66
}
61
67
62
- glog .Info ("Starting a new server..." )
63
- handler .Server = mq .NewServer (handler .QueueURL , mq .HandlerFunc (func (m * mq.Message ) error {
64
- return handler .HandleSQSMessage (aws .StringValue (m .SQSMessage .Body ))
65
- }), mq .WithClient (newClient ))
66
- handler .Server .Start ()
67
- glog .Info ("The server is started" )
68
+ receiveParams := & sqs.ReceiveMessageInput {
69
+ QueueUrl : aws .String (handler .QueueURL ),
70
+ MaxNumberOfMessages : aws .Int64 (1 ),
71
+ VisibilityTimeout : aws .Int64 (30 ),
72
+ WaitTimeSeconds : aws .Int64 (20 ),
73
+ }
74
+ for {
75
+ time .Sleep (1 * time .Second )
76
+ receiveResp , err := newClient .ReceiveMessage (receiveParams )
77
+ if err != nil {
78
+ glog .Error (err )
79
+ }
68
80
69
- go handler .StartMonitoringProcess ()
70
- go handler .RemoveCompletedJobsProcess ()
81
+ for _ , message := range receiveResp .Messages {
82
+ err := handler .HandleSQSMessage (message )
83
+ if err != nil {
84
+ glog .Errorf ("Can not process the message. Error %s. Message %s" , err , * message .Body )
85
+ continue
86
+ }
87
+
88
+ handler .RemoveSQSMessage (message )
89
+
90
+ }
71
91
92
+ }
93
+ }
94
+
95
+ // RemoveSQSMessage removes SQS message
96
+ func (handler * SQSHandler ) RemoveSQSMessage (message * sqs.Message ) error {
97
+ newClient , err := NewSQSClient ()
98
+ if err != nil {
99
+ return err
100
+ }
101
+ deleteParams := & sqs.DeleteMessageInput {
102
+ QueueUrl : aws .String (handler .QueueURL ), // Required
103
+ ReceiptHandle : message .ReceiptHandle , // Required
104
+ }
105
+ _ , err = newClient .DeleteMessage (deleteParams ) // No response returned when successed.
106
+ if err != nil {
107
+ glog .Error (err )
108
+ return err
109
+ }
110
+ glog .Infof ("Message ID: %s has beed deleted.\n \n " , * message .MessageId )
72
111
return nil
112
+ }
113
+
114
+ // ResendSQSMessage resends the message
115
+ func (handler * SQSHandler ) ResendSQSMessage (queueURL string , message * sqs.Message ) error {
116
+ newClient , err := NewSQSClient ()
117
+ if err != nil {
118
+ return err
119
+ }
120
+ sentMessageInput := & sqs.SendMessageInput {
121
+ MessageBody : message .Body ,
122
+ QueueUrl : aws .String (queueURL ),
123
+ }
124
+ _ , err = newClient .SendMessage (sentMessageInput )
125
+ return err
73
126
74
127
}
75
128
@@ -81,7 +134,8 @@ func (handler *SQSHandler) StartMonitoringProcess() {
81
134
for _ , jobInfo := range handler .MonitoredJobs {
82
135
k8sJob , err := GetJobStatusByID (jobInfo .UID )
83
136
if err != nil {
84
- glog .Errorf ("Can not get k8s job %s. Detail %s" , jobInfo .Name , err )
137
+ glog .Errorf ("Can not get k8s job %s. Detail %s. Resend the message to the queue" , jobInfo .Name , err )
138
+ handler .ResendSQSMessage (handler .QueueURL , jobInfo .SQSMessage )
85
139
} else {
86
140
glog .Infof ("%s: %s" , k8sJob .Name , k8sJob .Status )
87
141
if k8sJob .Status == "Unknown" || k8sJob .Status == "Running" {
@@ -107,17 +161,6 @@ func (handler *SQSHandler) RemoveCompletedJobsProcess() {
107
161
}
108
162
}
109
163
110
- // ShutdownServer shutdowns a server
111
- func (handler * SQSHandler ) ShutdownServer () error {
112
- fmt .Println ("Shutdown the server" )
113
- if handler .Server == nil {
114
- return nil
115
- }
116
- err := handler .Server .Shutdown (context .Background ())
117
- handler .Server = nil
118
- return err
119
- }
120
-
121
164
/*
122
165
getObjectFromSQSMessage returns s3 object from sqs message
123
166
@@ -202,8 +245,9 @@ to the queue and retry later (handled by `md` library). That makes sure
202
245
the message is properly handle before it actually deleted
203
246
204
247
*/
205
- func (handler * SQSHandler ) HandleSQSMessage (jsonBody string ) error {
248
+ func (handler * SQSHandler ) HandleSQSMessage (message * sqs. Message ) error {
206
249
250
+ jsonBody := * message .Body
207
251
objectPaths := getObjectsFromSQSMessage (jsonBody )
208
252
209
253
jobNameList := make ([]string , 0 )
@@ -220,21 +264,24 @@ func (handler *SQSHandler) HandleSQSMessage(jsonBody string) error {
220
264
}
221
265
}
222
266
}
267
+ glog .Info ("message:" , jsonBody )
223
268
224
269
glog .Infof ("Start to run %d jobs" , len (jobMap ))
225
270
226
271
for objectPath , jobConfig := range jobMap {
227
272
for GetNumberRunningJobs () > GetMaxJobConfig () {
228
273
time .Sleep (5 * time .Second )
229
274
}
230
- glog .Info ("Processing: " , objectPath )
231
275
jobInfo , err := CreateK8sJob (objectPath , jobConfig )
232
276
if err != nil {
277
+ glog .Infof ("Error :%s" , err )
233
278
glog .Errorln (err )
234
279
return err
235
280
}
281
+ jobInfo .SQSMessage = message
236
282
out , err := json .Marshal (jobInfo )
237
283
if err != nil {
284
+ glog .Infof ("Error :%s" , err )
238
285
glog .Errorln (err )
239
286
return err
240
287
}
@@ -296,5 +343,8 @@ func (handler *SQSHandler) RetryCreateIndexingJob(jsonBytes []byte) error {
296
343
str := fmt .Sprintf (`{
297
344
"Type" : "Notification",
298
345
"Message" : "{\"Records\":[{\"eventSource\":\"aws:s3\",\"awsRegion\":\"us-east-1\",\"eventName\":\"ObjectCreated:Put\",\"s3\":{\"s3SchemaVersion\":\"1.0\",\"bucket\":{\"name\":\"%s\"},\"object\":{\"key\":\"%s\"}}}]}"}` , retryMessage .Bucket , retryMessage .Key )
299
- return handler .HandleSQSMessage (str )
346
+ sqsMessage := sqs.Message {}
347
+ sqsMessage .SetBody (str )
348
+
349
+ return handler .HandleSQSMessage (& sqsMessage )
300
350
}
0 commit comments