Skip to content

Commit 072104b

Browse files
committed
Merge branch 'master' of bitbucket.org:aldor007/go-img
2 parents 9add6cb + 0681183 commit 072104b

File tree

11 files changed

+268
-54
lines changed

11 files changed

+268
-54
lines changed

Dockerfile

-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ ADD . /go/src/mort
5555

5656
# when dep will be ready
5757
RUN cd /go/src/mort && dep ensure -vendor-only
58-
RUN go get -u go.uber.org/zap
5958
# RUN goinstall
6059
RUN cd /go/src/mort; go build cmd/mort.go; cp mort /go/mort; cp -r /go/src/mort/configuration /go/
6160
# clean up

Gopkg.lock

+27-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/mort.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ func main() {
2323
logger, _ := zap.NewDevelopment()
2424
zap.ReplaceGlobals(logger)
2525
log.RegisterLogger(logger.Sugar())
26+
rp := mort.NewRequestProcessor(5)
2627

2728
imgConfig := config.GetInstance()
2829
imgConfig.Load(*configPath)
2930
// Echo instance
3031
e := echo.New()
3132

3233
e.Use(mort.S3AuthMiddleware(imgConfig))
34+
// TODO: change echo to pressly/chi
3335

3436
// Route => handler
3537
e.Any ("/*", func(ctx echo.Context) error {
@@ -39,13 +41,16 @@ func main() {
3941
return ctx.NoContent(400)
4042
}
4143

42-
// dodac placeholder
43-
res := mort.Process(ctx, obj)
44+
res := rp.Process(ctx, obj)
45+
res.SetDebug(ctx.Request().Header.Get("X-Mort-Debug"))
4446
res.WriteHeaders(ctx.Response())
45-
defer res.Close()
4647
defer logger.Sync() // flushes buffer, if any
48+
if res.HasError() {
49+
log.Log().Warnw("Mort process error", "error", res.Error())
50+
}
51+
52+
return res.Write(ctx)
4753

48-
return ctx.Stream(res.StatusCode, res.ContentType, res.Stream)
4954
})
5055

5156

config/yaml.go

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type Storage struct {
4949
Region string `yaml:"region",omitempty`
5050
Endpoint string `yaml:"endpoint",omitempty`
5151
PathPrefix string `yaml:"pathPrefix",omitempty"`
52+
AllowMetadata bool `yaml:"allowMetadata",omitempty"`
5253
}
5354

5455
type StorageTypes map[string]Storage

configuration/config.yml

+11-11
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ buckets:
7373
mode: line
7474
storages:
7575
basic:
76-
kind: "local"
76+
kind: "local-meta"
7777
rootPath: "/Users/aldor/workspace/mkaciubacom/web"
7878
transform:
79-
kind: "local"
79+
kind: "local-meta"
8080
rootPath: "/Users/aldor/workspace/mkaciubacom/web"
81-
media2:
81+
media:
8282
keys:
8383
- accessKey: "acc"
8484
secretAccessKey: "sec"
@@ -150,13 +150,13 @@ buckets:
150150
headers:
151151
"x-security-key": "123qwe123qwe"
152152
transform:
153-
# kind: "local"
154-
# rootPath: "/Users/aldor/workspace/mkaciubacom/web"
155-
# pathPrefix: "transforms"
156-
kind: "http"
157-
url: "https://mkaciuba.pl/download<item>"
158-
headers:
159-
"x-security-key": "123qwe123qwe"
153+
kind: "local-meta"
154+
rootPath: "/Users/aldor/workspace/mkaciubacom/web"
155+
pathPrefix: "transforms"
156+
# kind: "http"
157+
# url: "https://mkaciuba.pl/download<item>"
158+
# headers:
159+
# "x-security-key": "123qwe123qwe"
160160
basic:
161-
kind: "local"
161+
kind: "local-meta"
162162
rootPath: "/Users/aldor/workspace/mkaciubacom/web"

engine/image_engine.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"mort/transforms"
1111
"mort/response"
1212
"mort/object"
13-
//Logger "github.com/labstack/gommon/log"
13+
"mort/log"
1414
)
1515

1616
type ImageEngine struct {
@@ -35,19 +35,22 @@ func (self *ImageEngine) Process(obj *object.FileObject, trans []transforms.Tran
3535
}
3636
}
3737

38-
hash := murmur3.New32()
38+
hash := murmur3.New64()
3939
hash.Write([]byte(obj.Key))
4040
//hash.Write([]byte(len(trans)))
4141

4242
res := response.NewBuf(200, buf)
4343
res.SetContentType("image/" + bimg.DetermineImageTypeName(buf))
4444
res.Set("cache-control", "max-age=6000, public")
45-
res.Set("last-modified", time.Now().Format(time.RFC1123))
46-
res.Set("etag", strconv.FormatInt(int64(hash.Sum32()), 16))
45+
res.Set("Last-Modified", time.Now().Format(time.RFC1123))
46+
res.Set("ETag", strconv.FormatInt(int64(hash.Sum64()), 16))
4747
meta, err := bimg.Metadata(buf)
4848
if err == nil {
4949
res.Set("x-amz-public-width", strconv.Itoa(meta.Size.Width))
5050
res.Set("x-amz-public-height", strconv.Itoa(meta.Size.Height))
51+
52+
} else {
53+
log.Log().Warnw("ImageEngine/process unable to process", "obj.key", obj.Key, "err", err)
5154
}
5255

5356
return res, nil

object/file_object.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func NewFileObject(uri string, mortConfig *config.Config) (*FileObject, error) {
4646
obj.Uri = uri
4747

4848
err := obj.decode(mortConfig)
49-
log.Log().Infow("New FileObject", "path", uri, "key", obj.Key, "bucket", obj.Bucket, "storage", obj.Storage,
49+
log.Log().Infow("New FileObject", "path", uri, "key", obj.Key, "bucket", obj.Bucket, "storage", obj.Storage.Kind,
5050
"hasTransforms", obj.HasTransform(), "hasParent" , obj.HasParent())
5151
return &obj, err
5252
}

processor.go

+94-12
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,59 @@ import (
1515
"mort/transforms"
1616
"mort/log"
1717
"strconv"
18+
"time"
1819
)
20+
1921
const S3_LOCATION_STR = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><LocationConstraint xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">EU</LocationConstraint>"
2022

21-
func Process(ctx echo.Context, obj *object.FileObject) *response.Response {
23+
func NewRequestProcessor(max int) RequestProcessor{
24+
rp := RequestProcessor{}
25+
rp.Init(max)
26+
return rp
27+
}
28+
29+
type requestMessage struct {
30+
responseChan chan *response.Response
31+
ctx echo.Context
32+
obj *object.FileObject
33+
}
34+
35+
type RequestProcessor struct {
36+
queue chan requestMessage
37+
}
38+
39+
func (r *RequestProcessor) Init(max int) {
40+
r.queue = make(chan requestMessage, max)
41+
}
42+
43+
func (r *RequestProcessor) Process(ctx echo.Context, obj *object.FileObject) *response.Response{
44+
45+
msg := requestMessage{}
46+
msg.ctx = ctx
47+
msg.obj = obj
48+
msg.responseChan = make(chan *response.Response)
49+
50+
go r.processChan()
51+
r.queue <- msg
52+
53+
select {
54+
//case <-ctx.Done():
55+
// return response.NewBuf(504, "timeout")
56+
case res := <-msg.responseChan:
57+
return res
58+
case <-time.After(time.Second * 60):
59+
return response.NewBuf(504, []byte("timeout"))
60+
}
61+
}
62+
63+
func (r *RequestProcessor) processChan() {
64+
msg := <- r.queue
65+
res := r.process(msg.ctx, msg.obj)
66+
msg.responseChan <- res
67+
}
68+
69+
70+
func (r *RequestProcessor) process(ctx echo.Context, obj *object.FileObject) *response.Response {
2271
switch ctx.Request().Method {
2372
case "GET":
2473
return hanldeGET(ctx, obj)
@@ -57,25 +106,58 @@ func hanldeGET(ctx echo.Context, obj *object.FileObject) *response.Response {
57106
}
58107
}
59108

109+
resChan := make(chan *response.Response)
110+
parentChan := make(chan *response.Response)
111+
112+
go func(o *object.FileObject) {
113+
resChan <- storage.Get(o)
114+
}(obj)
115+
60116
// get parent from storage
61117
if parentObj != nil {
62-
parentRes = updateHeaders(storage.Get(parentObj))
63-
64-
if parentRes.StatusCode != 200 {
65-
return parentRes
66-
}
118+
go func(p *object.FileObject) {
119+
parentChan <- storage.Head(p)
120+
}(parentObj)
67121
}
68122

69-
// check if object is on storage
70-
res = updateHeaders(storage.Get(obj))
71-
if res.StatusCode == 200 {
72-
return res
73-
}
123+
resLoop:
124+
for {
125+
select {
126+
case res = <-resChan:
127+
if parentObj != nil && (parentRes == nil || parentRes.StatusCode == 0) {
128+
go func () {
129+
resChan <- res
130+
}()
131+
132+
} else {
133+
if res.StatusCode == 200 && parentRes.StatusCode == 200 {
134+
return updateHeaders(res)
135+
}
74136

75-
defer parentRes.Close()
137+
if res.StatusCode == 404 {
138+
break resLoop
139+
} else {
140+
return updateHeaders(res)
141+
}
142+
}
143+
case parentRes = <-parentChan:
144+
if parentRes.StatusCode == 404 {
145+
return updateHeaders(parentRes)
146+
}
147+
default:
148+
149+
}
150+
}
76151

77152
if obj.HasTransform() && strings.Contains(parentRes.ContentType, "image/") {
78153
defer res.Close()
154+
parentRes = updateHeaders(storage.Get(parentObj))
155+
156+
if parentRes.StatusCode != 200 {
157+
return updateHeaders(parentRes)
158+
}
159+
160+
defer parentRes.Close()
79161

80162
// revers order of transforms
81163
for i := 0; i < len(transforms)/2; i++ {

0 commit comments

Comments
 (0)