Skip to content

Commit

Permalink
added support for collaboration.
Browse files Browse the repository at this point in the history
  • Loading branch information
hxhxhx88 committed Mar 31, 2024
1 parent 43168af commit d5bad6c
Show file tree
Hide file tree
Showing 85 changed files with 11,682 additions and 382 deletions.
11 changes: 9 additions & 2 deletions .github/workflows/pretest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ jobs:
FROM project-dev
ADD . /project
# create an empty file to make `go:embed` happy
RUN cd /project && mkdir app/frontend/build && touch app/frontend/build/test && mkdir docs/build && touch docs/build/test
# create empty files to make `go:embed` happy
RUN \
cd /project && \
mkdir app/frontend/build && \
touch app/frontend/build/test && \
mkdir docs/build && \
touch docs/build/test && \
mkdir app/yjs-server/bin && \
touch app/yjs-server/bin/yjs-server
# generate code
RUN cd /project && task openapi && task proto
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ jobs:
task frontend:build && \
task docs:build
RUN \
GOOS=linux GOARCH=amd64 task backend:build && mv build/nutsh build/nutsh-Linux-x86_64 && \
GOOS=linux GOARCH=arm64 task backend:build && mv build/nutsh build/nutsh-Linux-arm64 && \
GOOS=darwin GOARCH=amd64 task backend:build && mv build/nutsh build/nutsh-Darwin-x86_64 && \
GOOS=darwin GOARCH=arm64 task backend:build && mv build/nutsh build/nutsh-Darwin-arm64
GOOS=linux GOARCH=amd64 task yjs:build && task backend:build && mv build/nutsh build/nutsh-Linux-x86_64 && \
GOOS=linux GOARCH=arm64 task yjs:build && task backend:build && mv build/nutsh build/nutsh-Linux-arm64 && \
GOOS=darwin GOARCH=amd64 task yjs:build && task backend:build && mv build/nutsh build/nutsh-Darwin-x86_64 && \
GOOS=darwin GOARCH=arm64 task yjs:build && task backend:build && mv build/nutsh build/nutsh-Darwin-arm64
RUN \
GOOS=linux GOARCH=amd64 task sam:build && mv build/nutsh-sam build/nutsh-sam-Linux-x86_64 && \
GOOS=linux GOARCH=arm64 task sam:build && mv build/nutsh-sam build/nutsh-sam-Linux-arm64 && \
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ openapi/gen
build
local
*.local
__pycache__
__pycache__
bin
3 changes: 3 additions & 0 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ vars:
includes:
frontend: task/frontend.yaml
backend: task/backend.yaml
yjs: task/yjs.yaml
e2e: task/e2e.yaml
container: task/container.yaml
deploy: task/deploy.yaml
Expand Down Expand Up @@ -45,13 +46,15 @@ tasks:
build:
cmds:
- rm -f build/nutsh
- task: yjs:build
- task: frontend:build
- task: docs:build
- task: backend:build

build-dev:
cmds:
- rm -f build/nutsh-dev
- task: yjs:build
- task: frontend:build-dev
- task: backend:build
- mv build/nutsh build/nutsh-dev
Expand Down
5 changes: 3 additions & 2 deletions app/action/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ var StorageOption struct {
}

var StartOption struct {
Frontend fs.FS
Doc fs.FS
Frontend fs.FS
YJSServer []byte
Doc fs.FS

Port int
Readonly bool
Expand Down
145 changes: 120 additions & 25 deletions app/action/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ package action
import (
"context"
"fmt"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"os/exec"
"path/filepath"

"github.com/labstack/echo/v4"
Expand Down Expand Up @@ -33,30 +37,12 @@ func Start(ctx context.Context) error {
e.HideBanner = true
middlewares := []echo.MiddlewareFunc{
middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
LogURI: true,
LogStatus: true,
LogMethod: true,
LogLatency: true,
LogError: true,
LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
// https://github.com/labstack/echo/issues/2015
status := v.Status
if v.Error != nil {
switch e := v.Error.(type) {
case *echo.HTTPError:
status = e.Code
default:
status = http.StatusInternalServerError
}
}
zap.L().Info("request",
zap.String("method", v.Method),
zap.String("uri", v.URI),
zap.Duration("latency", v.Latency),
zap.Int("status", status),
)
return nil
},
LogURI: true,
LogStatus: true,
LogMethod: true,
LogLatency: true,
LogError: true,
LogValuesFunc: logValuesFunc,
}),
middleware.GzipWithConfig(middleware.GzipConfig{
Level: 9,
Expand All @@ -68,6 +54,26 @@ func Start(ctx context.Context) error {
}
e.Use(middlewares...)

// proxy yjs-server ws
yjsPort := mustStartYJSServer()
e.Any("/ws/*", func(c echo.Context) error {
target := fmt.Sprintf("http://127.0.0.1:%d", yjsPort)
targetUrl, err := url.Parse(target)
if err != nil {
return err
}

proxy := httputil.NewSingleHostReverseProxy(targetUrl)
proxy.Director = func(req *http.Request) {
req.URL.Scheme = targetUrl.Scheme
req.URL.Host = targetUrl.Host
req.URL.Path = "/" + c.Param("*")
}

proxy.ServeHTTP(c.Response(), c.Request())
return nil
})

// local data
if StartOption.DataDir != "" {
zap.L().Info("serving local data", zap.String("dir", StartOption.DataDir))
Expand Down Expand Up @@ -105,11 +111,31 @@ func Start(ctx context.Context) error {
return e.Start(lisAddr)
}

func logValuesFunc(c echo.Context, v middleware.RequestLoggerValues) error {
// https://github.com/labstack/echo/issues/2015
status := v.Status
if v.Error != nil {
switch e := v.Error.(type) {
case *echo.HTTPError:
status = e.Code
default:
status = http.StatusInternalServerError
}
}
zap.L().Info("request",
zap.String("method", v.Method),
zap.String("uri", v.URI),
zap.Duration("latency", v.Latency),
zap.Int("status", status),
)
return nil
}

func createServer() (backend.Server, func(), error) {
var opts []backend.Option

// storage
db, err := sqlite3.New(filepath.Join(databaseDir(), "db.sqlite3"))
db, err := sqlite3.New(databasePath())
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -190,3 +216,72 @@ func databaseDir() string {
}
return filepath.Join(StorageOption.Workspace, "database")
}

func databasePath() string {
return filepath.Join(databaseDir(), "db.sqlite3")
}

func mustStartYJSServer() int {
// create a temporary file
bin, err := os.CreateTemp("", "nutsh-yjs-*")
mustOk(err)

// write the embedded binary to the temporary file
_, err = bin.Write(StartOption.YJSServer)
mustOk(err)
mustOk(bin.Close())

// make the file executable
mustOk(os.Chmod(bin.Name(), 0755))

// prepare arguments
internalPort := mustFindFreePort()

// set envs
envs := []string{
fmt.Sprintf("PORT=%d", internalPort),
fmt.Sprintf("DATABASE_PATH=%s", databasePath()),
}
if StartOption.Readonly {
envs = append(envs, "READ_ONLY=true")
}

// execute the binary in a new process
cmd := exec.Command(bin.Name())
cmd.Env = envs
zap.L().Info("start yjs-server server", zap.Int("port", internalPort))

cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout

go func() {
defer os.Remove(bin.Name())
mustOk(cmd.Run())
}()

return internalPort
}

func mustFindFreePort() int {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
mustOk(err)

l, err := net.ListenTCP("tcp", addr)
mustOk(err)
defer l.Close()

return l.Addr().(*net.TCPAddr).Port
}

func mustOk(err error) {
if err == nil {
return
}

if os.Getenv("DEBUG") != "" {
fmt.Printf("%+v\n", err)
} else {
fmt.Printf("%v\n", err)
}
os.Exit(1)
}
2 changes: 1 addition & 1 deletion app/backend/segmentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (s *mServer) GetOnlineSegmentation(ctx context.Context, request nutshapi.Ge
return resp, nil
}

func (s *mServer) getOnlineSegmentation(ctx context.Context, request nutshapi.GetOnlineSegmentationRequestObject) (nutshapi.GetOnlineSegmentationResponseObject, error) {
func (s *mServer) getOnlineSegmentation(ctx context.Context, _ nutshapi.GetOnlineSegmentationRequestObject) (nutshapi.GetOnlineSegmentationResponseObject, error) {
opts := s.options
store := opts.storagePublic

Expand Down
18 changes: 11 additions & 7 deletions app/frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"extends": [
"./node_modules/gts/",
"plugin:react/jsx-runtime"
],
"extends": ["./node_modules/gts/", "plugin:react/jsx-runtime"],
"plugins": ["react-hooks"],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
}
},
"overrides": [
{
// I don't know why `eslint-disable-next-line` does not work for webpack, so I configure here as a workaround.
"files": ["src/state/annotate/annotation-broadcast.ts"],
"rules": {"@typescript-eslint/no-explicit-any": "off"}
}
]
}
4 changes: 4 additions & 0 deletions app/frontend/craco.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// eslint-disable-next-line node/no-unpublished-require
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');

module.exports = {
webpack: {
alias: {
'@@frontend': path.resolve(__dirname, 'src/'),
},
configure: config => {
config.plugins.push(
new CopyWebpackPlugin({
Expand Down
Loading

0 comments on commit d5bad6c

Please sign in to comment.