Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
db72c24de3
|
|||
|
87170420e4
|
|||
|
2e79ac4460
|
|||
|
cd1f1d7b5f
|
|||
|
a3ee0b7900
|
|||
|
114c7101d6
|
|||
| 41476d04a2 | |||
| a5780449fc | |||
| 4784c1c380 | |||
| 6bb1d524b9 | |||
| bcadac0f07 | |||
| 1a2087f2ee | |||
| f2069de1ec | |||
| cdc7d62440 | |||
| 5180a93ee6 | |||
| 864a130df4 | |||
| 27607eb867 | |||
| aa0782a800 | |||
| 8c879b31c2 | |||
| f5ed427dd2 |
@@ -5,7 +5,7 @@ After=syslog.target network.target
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/local/bin/ev
|
ExecStart=/usr/local/bin/ev
|
||||||
|
User=www-data
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=30
|
RestartSec=30
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Copy build to remote
|
- name: Copy build to remote
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: ../build/ev
|
src: ../ev
|
||||||
dest: /usr/local/bin/ev
|
dest: /usr/local/bin/ev
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
||||||
- name: Copy build to remote
|
# - name: Copy build to remote
|
||||||
ansible.builtin.copy:
|
# ansible.builtin.copy:
|
||||||
src: ev.service
|
# src: ev.service
|
||||||
dest: /etc/systemd/system/ev.service
|
# dest: /etc/systemd/system/ev.service
|
||||||
owner: root
|
# owner: root
|
||||||
group: root
|
# group: root
|
||||||
|
|
||||||
- name: Restart service
|
- name: Restart service
|
||||||
systemd:
|
systemd:
|
||||||
|
|||||||
25
.gitea/workflows/bump-push.yml
Normal file
25
.gitea/workflows/bump-push.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: Go Bump
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
bump:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.21.1
|
||||||
|
|
||||||
|
- run: go install github.com/psanetra/git-semver/cli@master
|
||||||
|
|
||||||
|
- run: git tag v$(cli next --stable=false) && git push --tags || echo no change
|
||||||
|
|
||||||
|
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||||
@@ -1,28 +1,30 @@
|
|||||||
name: Go Bump
|
name: Go Bump
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# workflow_dispatch:
|
workflow_dispatch:
|
||||||
# inputs:
|
inputs:
|
||||||
# stable:
|
NAME:
|
||||||
# description: 'Stable Release'
|
description: "A random input name for the workflow"
|
||||||
# required: false
|
type: string
|
||||||
# type: boolean
|
SOME_VALUE:
|
||||||
# prerelease:
|
description: "Some other input to pass"
|
||||||
# description: 'Pre Release'
|
type: string
|
||||||
# required: false
|
|
||||||
# type: boolean
|
# push:
|
||||||
push:
|
# branches: [ "main" ]
|
||||||
branches: [ "main" ]
|
# pull_request:
|
||||||
pull_request:
|
# branches: [ "main" ]
|
||||||
branches: [ "main" ]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
bump:
|
bump:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- run: echo stable=${{ inputs.stable }} pre=${{ inputs.prerelease }}
|
- run: echo stable=${{ inputs.STABLE }} pre=${{ inputs.BETA }}
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
name: Deploy
|
name: Deploy
|
||||||
|
|
||||||
on:
|
on:
|
||||||
# push:
|
push:
|
||||||
# branches: [ "main" ]
|
branches: [ "main" ]
|
||||||
release:
|
release:
|
||||||
types: [ published ]
|
types: [ published ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- run: apt-get update && apt-get -y install ansible
|
- run: apt-get update && apt-get -y install ansible
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
@@ -19,15 +18,17 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: 1.21.1
|
go-version: 1.21.1
|
||||||
|
|
||||||
- name: Build
|
- name: Install
|
||||||
run: go build -ldflags "-s -w" -o ./build/ev ./cmd/ev
|
run: go install -ldflags "-s -w" go.sour.is/tools/cmd/ev@latest
|
||||||
|
|
||||||
|
- run: mv $(go env GOPATH)/bin/ev ev
|
||||||
|
|
||||||
- name: Compress
|
- name: Compress
|
||||||
uses: https://git.sour.is/actions/ghaction-upx@v2.4.0
|
uses: https://git.sour.is/actions/ghaction-upx@v2.4.0
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
files: |
|
files: |
|
||||||
./build/ev
|
./ev
|
||||||
args: -fq
|
args: -fq
|
||||||
|
|
||||||
- name: Deploy
|
- name: Deploy
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
tools
|
tools
|
||||||
|
sour.is-tools
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -1,6 +1,6 @@
|
|||||||
export PATH:=$(shell go env GOPATH)/bin:$(PATH)
|
export PATH:=$(shell go env GOPATH)/bin:$(PATH)
|
||||||
export EV_DATA=mem:
|
export EV_DATA=mem:
|
||||||
export EV_HTTP=:8080
|
export EV_HTTP=:8085
|
||||||
export WEBFINGER_DOMAINS=localhost
|
export WEBFINGER_DOMAINS=localhost
|
||||||
|
|
||||||
.DEFAULT_GOAL := air
|
.DEFAULT_GOAL := air
|
||||||
@@ -15,7 +15,7 @@ endif
|
|||||||
air .
|
air .
|
||||||
|
|
||||||
run:
|
run:
|
||||||
go build . && ./tools
|
go build -buildvcs=true -o sour.is-tools ./cmd/ev && ./sour.is-tools
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -cover -race ./...
|
go test -cover -race ./...
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ func (s *service) getPending(w http.ResponseWriter, r *http.Request, peerID stri
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.RecordError(err)
|
span.AddEvent(err.Error())
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -204,8 +204,9 @@ func (s *service) getPending(w http.ResponseWriter, r *http.Request, peerID stri
|
|||||||
peerResults.SetStreamID(aggPeer(peerID))
|
peerResults.SetStreamID(aggPeer(peerID))
|
||||||
err = s.es.Load(ctx, peerResults)
|
err = s.es.Load(ctx, peerResults)
|
||||||
if err != nil && !errors.Is(err, ev.ErrNotFound) {
|
if err != nil && !errors.Is(err, ev.ErrNotFound) {
|
||||||
span.RecordError(fmt.Errorf("peer not found: %w", err))
|
span.AddEvent("peer not found")
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req *Request
|
var req *Request
|
||||||
@@ -221,8 +222,9 @@ func (s *service) getPending(w http.ResponseWriter, r *http.Request, peerID stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if req == nil {
|
if req == nil {
|
||||||
span.RecordError(fmt.Errorf("request not found"))
|
span.AddEvent("request not found")
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
negotiator := contentnegotiation.NewNegotiator("application/json", "text/environment", "text/plain", "text/html")
|
negotiator := contentnegotiation.NewNegotiator("application/json", "text/environment", "text/plain", "text/html")
|
||||||
@@ -304,7 +306,7 @@ func (s *service) getResults(w http.ResponseWriter, r *http.Request) {
|
|||||||
sort.Sort(sort.Reverse(requests))
|
sort.Sort(sort.Reverse(requests))
|
||||||
|
|
||||||
args := requestArgs(r)
|
args := requestArgs(r)
|
||||||
args.Requests = requests[:maxResults]
|
args.Requests = requests[:min(maxResults, len(requests))]
|
||||||
|
|
||||||
s.state.Use(ctx, func(ctx context.Context, state *state) error {
|
s.state.Use(ctx, func(ctx context.Context, state *state) error {
|
||||||
args.CountPeers = len(state.peers)
|
args.CountPeers = len(state.peers)
|
||||||
@@ -433,8 +435,8 @@ func (s *service) postResult(w http.ResponseWriter, r *http.Request, reqID strin
|
|||||||
err := s.state.Use(ctx, func(ctx context.Context, state *state) error {
|
err := s.state.Use(ctx, func(ctx context.Context, state *state) error {
|
||||||
var ok bool
|
var ok bool
|
||||||
if _, ok = state.peers[peerID]; !ok {
|
if _, ok = state.peers[peerID]; !ok {
|
||||||
log.Printf("peer not found: %s\n", peerID)
|
log.Printf("peer not found: req=%s peer=%s\n", reqID, peerID)
|
||||||
return fmt.Errorf("peer not found: %s", peerID)
|
return fmt.Errorf("peer not found: req=%s peer=%s", reqID, peerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -448,9 +450,10 @@ func (s *service) postResult(w http.ResponseWriter, r *http.Request, reqID strin
|
|||||||
peerResults := &PeerResults{}
|
peerResults := &PeerResults{}
|
||||||
peerResults.SetStreamID(aggPeer(peerID))
|
peerResults.SetStreamID(aggPeer(peerID))
|
||||||
err = s.es.Load(ctx, peerResults)
|
err = s.es.Load(ctx, peerResults)
|
||||||
if err != nil {
|
if err != nil && !errors.Is(err, ev.ErrNotFound) {
|
||||||
span.RecordError(fmt.Errorf("peer not found: %w", err))
|
span.RecordError(fmt.Errorf("peer not found: req=%s peer=%s %w", reqID, peerID, err))
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if peerResults.Has(reqID) {
|
if peerResults.Has(reqID) {
|
||||||
|
|||||||
@@ -91,17 +91,17 @@ func (s *service) Run(ctx context.Context) (err error) {
|
|||||||
subRes, e := s.es.EventStream().Subscribe(ctx, queueResults, 0)
|
subRes, e := s.es.EventStream().Subscribe(ctx, queueResults, 0)
|
||||||
errs = multierr.Append(errs, e)
|
errs = multierr.Append(errs, e)
|
||||||
|
|
||||||
|
if errs != nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
err = multierr.Combine(subReq.Close(ctx), subRes.Close(ctx), err)
|
err = multierr.Combine(err, subReq.Close(ctx), subRes.Close(ctx))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if errs != nil {
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var events event.Events
|
var events event.Events
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"go.sour.is/pkg/env"
|
||||||
"go.sour.is/pkg/lg"
|
"go.sour.is/pkg/lg"
|
||||||
"go.sour.is/pkg/service"
|
"go.sour.is/pkg/service"
|
||||||
)
|
)
|
||||||
@@ -27,6 +30,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
func run(ctx context.Context) error {
|
func run(ctx context.Context) error {
|
||||||
|
// TODO: make this configurable.
|
||||||
|
level := slog.LevelError
|
||||||
|
if ok, _ := strconv.ParseBool(env.Default("LOG_DEBUG", "FALSE")); ok {
|
||||||
|
level = slog.LevelDebug
|
||||||
|
}
|
||||||
|
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: level})))
|
||||||
|
|
||||||
svc := &service.Harness{}
|
svc := &service.Harness{}
|
||||||
ctx, stop := lg.Init(ctx, appName)
|
ctx, stop := lg.Init(ctx, appName)
|
||||||
svc.OnStop(stop)
|
svc.OnStop(stop)
|
||||||
|
|||||||
Reference in New Issue
Block a user