move the memory intensive and sometimes fragile image code
to a special backend process
This commit is contained in:
parent
02f73018ab
commit
8a6eaf5fe1
|
@ -34,7 +34,6 @@ import (
|
||||||
"humungus.tedunangst.com/r/webs/cache"
|
"humungus.tedunangst.com/r/webs/cache"
|
||||||
"humungus.tedunangst.com/r/webs/gate"
|
"humungus.tedunangst.com/r/webs/gate"
|
||||||
"humungus.tedunangst.com/r/webs/httpsig"
|
"humungus.tedunangst.com/r/webs/httpsig"
|
||||||
"humungus.tedunangst.com/r/webs/image"
|
|
||||||
"humungus.tedunangst.com/r/webs/junk"
|
"humungus.tedunangst.com/r/webs/junk"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -175,8 +174,7 @@ func savedonk(url string, name, desc, media string, localize bool) *Donk {
|
||||||
log.Printf("truncation likely")
|
log.Printf("truncation likely")
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(media, "image") {
|
if strings.HasPrefix(media, "image") {
|
||||||
img, err := image.Vacuum(&buf,
|
img, err := shrinkit(data)
|
||||||
image.Params{LimitSize: 4200 * 4200, MaxWidth: 2048, MaxHeight: 2048})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("unable to decode image: %s", err)
|
log.Printf("unable to decode image: %s", err)
|
||||||
localize = false
|
localize = false
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/rpc"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"humungus.tedunangst.com/r/webs/image"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Shrinker struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShrinkerArgs struct {
|
||||||
|
Buf []byte
|
||||||
|
Params image.Params
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShrinkerResult struct {
|
||||||
|
Image *image.Image
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Shrinker) Shrink(args *ShrinkerArgs, res *ShrinkerResult) error {
|
||||||
|
img, err := image.Vacuum(bytes.NewReader(args.Buf), args.Params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
res.Image = img
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func backendSockname() string {
|
||||||
|
return dataDir + "/backend.sock"
|
||||||
|
}
|
||||||
|
|
||||||
|
func shrinkit(data []byte) (*image.Image, error) {
|
||||||
|
cl, err := rpc.Dial("unix", backendSockname())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer cl.Close()
|
||||||
|
var res ShrinkerResult
|
||||||
|
err = cl.Call("Shrinker.Shrink", &ShrinkerArgs{
|
||||||
|
Buf: data,
|
||||||
|
Params: image.Params{LimitSize: 4200 * 4200, MaxWidth: 2048, MaxHeight: 2048},
|
||||||
|
}, &res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return res.Image, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func backendServer() {
|
||||||
|
log.Printf("backend server running")
|
||||||
|
shrinker := new(Shrinker)
|
||||||
|
srv := rpc.NewServer()
|
||||||
|
err := srv.Register(shrinker)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("unable to register shrinker: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sockname := backendSockname()
|
||||||
|
err = os.Remove(sockname)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
log.Panicf("unable to unlink socket: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lis, err := net.Listen("unix", sockname)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("unable to register shrinker: %s", err)
|
||||||
|
}
|
||||||
|
srv.Accept(lis)
|
||||||
|
}
|
||||||
|
|
||||||
|
func startBackendServer() {
|
||||||
|
proc := exec.Command(os.Args[0], "-datadir", dataDir, "backend")
|
||||||
|
proc.Stdout = os.Stdout
|
||||||
|
proc.Stderr = os.Stderr
|
||||||
|
err := proc.Start()
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("can't exec backend: %s", err)
|
||||||
|
}
|
||||||
|
}
|
2
honk.go
2
honk.go
|
@ -269,6 +269,8 @@ func main() {
|
||||||
ping(user, targ)
|
ping(user, targ)
|
||||||
case "run":
|
case "run":
|
||||||
serve()
|
serve()
|
||||||
|
case "backend":
|
||||||
|
backendServer()
|
||||||
case "test":
|
case "test":
|
||||||
ElaborateUnitTests()
|
ElaborateUnitTests()
|
||||||
default:
|
default:
|
||||||
|
|
4
web.go
4
web.go
|
@ -36,7 +36,6 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"humungus.tedunangst.com/r/webs/cache"
|
"humungus.tedunangst.com/r/webs/cache"
|
||||||
"humungus.tedunangst.com/r/webs/httpsig"
|
"humungus.tedunangst.com/r/webs/httpsig"
|
||||||
"humungus.tedunangst.com/r/webs/image"
|
|
||||||
"humungus.tedunangst.com/r/webs/junk"
|
"humungus.tedunangst.com/r/webs/junk"
|
||||||
"humungus.tedunangst.com/r/webs/login"
|
"humungus.tedunangst.com/r/webs/login"
|
||||||
"humungus.tedunangst.com/r/webs/rss"
|
"humungus.tedunangst.com/r/webs/rss"
|
||||||
|
@ -1399,7 +1398,7 @@ func submithonk(w http.ResponseWriter, r *http.Request) {
|
||||||
data := buf.Bytes()
|
data := buf.Bytes()
|
||||||
xid := xfiltrate()
|
xid := xfiltrate()
|
||||||
var media, name string
|
var media, name string
|
||||||
img, err := image.Vacuum(&buf, image.Params{MaxWidth: 2048, MaxHeight: 2048})
|
img, err := shrinkit(data)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
data = img.Data
|
data = img.Data
|
||||||
format := img.Format
|
format := img.Format
|
||||||
|
@ -2060,6 +2059,7 @@ func serve() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
startBackendServer()
|
||||||
go enditall()
|
go enditall()
|
||||||
go redeliverator()
|
go redeliverator()
|
||||||
go tracker()
|
go tracker()
|
||||||
|
|
Loading…
Reference in New Issue