@@ -43,16 +43,28 @@ import (
43
43
"gocloud.dev/pubsub"
44
44
)
45
45
46
- func NewFilesController (logger log.Logger , cfg service.HTTPConfig , pub stream.Publisher , cancellationResponses chan models.FileCancellationResponse ) * FilesController {
46
+ func NewFilesController (
47
+ logger log.Logger ,
48
+ cfg service.HTTPConfig ,
49
+ pub stream.Publisher ,
50
+ queueFileResponses chan incoming.QueueACHFileResponse ,
51
+ cancellationResponses chan models.FileCancellationResponse ,
52
+ ) * FilesController {
47
53
controller := & FilesController {
48
54
logger : logger ,
49
55
cfg : cfg ,
50
56
publisher : pub ,
51
57
58
+ activeQueueFiles : make (map [string ]chan incoming.QueueACHFileResponse ),
59
+ queueFileResponses : queueFileResponses ,
60
+
52
61
activeCancellations : make (map [string ]chan models.FileCancellationResponse ),
53
62
cancellationResponses : cancellationResponses ,
54
63
}
64
+
65
+ controller .listenForQueueACHFileResponses ()
55
66
controller .listenForCancellations ()
67
+
56
68
return controller
57
69
}
58
70
@@ -61,11 +73,45 @@ type FilesController struct {
61
73
cfg service.HTTPConfig
62
74
publisher stream.Publisher
63
75
76
+ queueFileLock sync.Mutex
77
+ activeQueueFiles map [string ]chan incoming.QueueACHFileResponse
78
+ queueFileResponses chan incoming.QueueACHFileResponse
79
+
64
80
cancellationLock sync.Mutex
65
81
activeCancellations map [string ]chan models.FileCancellationResponse
66
82
cancellationResponses chan models.FileCancellationResponse
67
83
}
68
84
85
+ func (c * FilesController ) listenForQueueACHFileResponses () {
86
+ c .logger .Info ().Log ("listening for QueueACHFile responses" )
87
+ go func () {
88
+ for {
89
+ // Wait for a message
90
+ resp := <- c .queueFileResponses
91
+ logger := c .logger .Info ().With (log.Fields {
92
+ "file_id" : log .String (resp .FileID ),
93
+ "shard_key" : log .String (resp .ShardKey ),
94
+ })
95
+
96
+ if resp .Error != "" {
97
+ logger .Error ().LogErrorf ("problem with QueueACHFile: %v" , resp .Error )
98
+ } else {
99
+ logger .Info ().Logf ("received QueueACHFile response" )
100
+ }
101
+
102
+ fileID := strings .TrimSuffix (resp .FileID , ".ach" )
103
+
104
+ c .queueFileLock .Lock ()
105
+ out , exists := c .activeQueueFiles [fileID ]
106
+ if exists {
107
+ out <- resp
108
+ delete (c .activeQueueFiles , fileID )
109
+ }
110
+ c .queueFileLock .Unlock ()
111
+ }
112
+ }()
113
+ }
114
+
69
115
func (c * FilesController ) listenForCancellations () {
70
116
c .logger .Info ().Log ("listening for cancellation responses" )
71
117
go func () {
@@ -121,9 +167,14 @@ func (c *FilesController) CreateFileHandler(w http.ResponseWriter, r *http.Reque
121
167
))
122
168
defer span .End ()
123
169
170
+ logger := c .logger .With (log.Fields {
171
+ "shard_key" : log .String (shardKey ),
172
+ "file_id" : log .String (fileID ),
173
+ })
174
+
124
175
bs , err := c .readBody (r )
125
176
if err != nil {
126
- c . logger .LogErrorf ("error reading file: %v" , err )
177
+ logger .LogErrorf ("error reading file: %v" , err )
127
178
w .WriteHeader (http .StatusBadRequest )
128
179
return
129
180
}
@@ -139,17 +190,30 @@ func (c *FilesController) CreateFileHandler(w http.ResponseWriter, r *http.Reque
139
190
file = * f
140
191
}
141
192
142
- if err := c .publishFile (ctx , shardKey , fileID , & file ); err != nil {
143
- c .logger .With (log.Fields {
144
- "shard_key" : log .String (shardKey ),
145
- "file_id" : log .String (fileID ),
146
- }).LogErrorf ("publishing file" , err )
193
+ waiter := make (chan incoming.QueueACHFileResponse , 1 )
194
+ if err := c .publishFile (ctx , shardKey , fileID , & file , waiter ); err != nil {
195
+ logger .LogErrorf ("publishing file" , err )
147
196
148
197
w .WriteHeader (http .StatusInternalServerError )
149
198
return
150
199
}
151
200
201
+ var response incoming.QueueACHFileResponse
202
+ select {
203
+ case resp := <- waiter :
204
+ response = resp
205
+
206
+ case <- time .After (10 * time .Second ):
207
+ response = incoming.QueueACHFileResponse {
208
+ FileID : fileID ,
209
+ ShardKey : shardKey ,
210
+ Error : "timeout exceeded" ,
211
+ }
212
+ }
213
+
214
+ w .Header ().Set ("Content-Type" , "application/json" )
152
215
w .WriteHeader (http .StatusOK )
216
+ json .NewEncoder (w ).Encode (response )
153
217
}
154
218
155
219
func (c * FilesController ) readBody (req * http.Request ) ([]byte , error ) {
@@ -167,7 +231,11 @@ func (c *FilesController) readBody(req *http.Request) ([]byte, error) {
167
231
return compliance .Reveal (c .cfg .Transform , bs )
168
232
}
169
233
170
- func (c * FilesController ) publishFile (ctx context.Context , shardKey , fileID string , file * ach.File ) error {
234
+ func (c * FilesController ) publishFile (ctx context.Context , shardKey , fileID string , file * ach.File , waiter chan incoming.QueueACHFileResponse ) error {
235
+ c .queueFileLock .Lock ()
236
+ c .activeQueueFiles [fileID ] = waiter
237
+ c .queueFileLock .Unlock ()
238
+
171
239
bs , err := compliance .Protect (c .cfg .Transform , models.Event {
172
240
Event : incoming.ACHFile {
173
241
FileID : fileID ,
@@ -207,7 +275,6 @@ func (c *FilesController) CancelFileHandler(w http.ResponseWriter, r *http.Reque
207
275
defer span .End ()
208
276
209
277
waiter := make (chan models.FileCancellationResponse , 1 )
210
-
211
278
err := c .cancelFile (ctx , shardKey , fileID , waiter )
212
279
if err != nil {
213
280
c .logger .With (log.Fields {
0 commit comments