all: Implement suture v4-api (#6947)

This commit is contained in:
Simon Frei
2020-11-17 13:19:04 +01:00
committed by GitHub
parent e8fc465ea8
commit 9524b51708
65 changed files with 617 additions and 693 deletions
+6 -4
View File
@@ -66,12 +66,12 @@ func newAPISrv(addr string, cert tls.Certificate, db database, repl replicator,
}
}
func (s *apiSrv) Serve() {
func (s *apiSrv) Serve(ctx context.Context) error {
if s.useHTTP {
listener, err := net.Listen("tcp", s.addr)
if err != nil {
log.Println("Listen:", err)
return
return err
}
s.listener = listener
} else {
@@ -93,7 +93,7 @@ func (s *apiSrv) Serve() {
tlsListener, err := tls.Listen("tcp", s.addr, tlsCfg)
if err != nil {
log.Println("Listen:", err)
return
return err
}
s.listener = tlsListener
}
@@ -107,9 +107,11 @@ func (s *apiSrv) Serve() {
MaxHeaderBytes: httpMaxHeaderBytes,
}
if err := srv.Serve(s.listener); err != nil {
err := srv.Serve(s.listener)
if err != nil {
log.Println("Serve:", err)
}
return err
}
var topCtx = context.Background()
+5 -8
View File
@@ -10,6 +10,7 @@
package main
import (
"context"
"log"
"sort"
"time"
@@ -37,7 +38,6 @@ type database interface {
type levelDBStore struct {
db *leveldb.DB
inbox chan func()
stop chan struct{}
clock clock
marshalBuf []byte
}
@@ -50,7 +50,6 @@ func newLevelDBStore(dir string) (*levelDBStore, error) {
return &levelDBStore{
db: db,
inbox: make(chan func(), 16),
stop: make(chan struct{}),
clock: defaultClock{},
}, nil
}
@@ -155,7 +154,7 @@ func (s *levelDBStore) get(key string) (DatabaseRecord, error) {
return rec, nil
}
func (s *levelDBStore) Serve() {
func (s *levelDBStore) Serve(ctx context.Context) error {
t := time.NewTimer(0)
defer t.Stop()
defer s.db.Close()
@@ -183,7 +182,7 @@ loop:
// the next.
t.Reset(databaseStatisticsInterval)
case <-s.stop:
case <-ctx.Done():
// We're done.
close(statisticsTrigger)
break loop
@@ -192,6 +191,8 @@ loop:
// Also wait for statisticsServe to return
<-statisticsDone
return nil
}
func (s *levelDBStore) statisticsServe(trigger <-chan struct{}, done chan<- struct{}) {
@@ -255,10 +256,6 @@ func (s *levelDBStore) statisticsServe(trigger <-chan struct{}, done chan<- stru
}
}
func (s *levelDBStore) Stop() {
close(s.stop)
}
// merge returns the merged result of the two database records a and b. The
// result is the union of the two address sets, with the newer expiry time
// chosen for any duplicates.
+4 -2
View File
@@ -7,6 +7,7 @@
package main
import (
"context"
"fmt"
"os"
"testing"
@@ -20,8 +21,9 @@ func TestDatabaseGetSet(t *testing.T) {
if err != nil {
t.Fatal(err)
}
go db.Serve()
defer db.Stop()
ctx, cancel := context.WithCancel(context.Background())
go db.Serve(ctx)
defer cancel()
// Check missing record
+3 -2
View File
@@ -7,6 +7,7 @@
package main
import (
"context"
"crypto/tls"
"flag"
"log"
@@ -21,7 +22,7 @@ import (
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/tlsutil"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/thejerf/suture"
"github.com/thejerf/suture/v4"
)
const (
@@ -183,5 +184,5 @@ func main() {
}
// Engage!
main.Serve()
main.Serve(context.Background())
}
+16 -27
View File
@@ -7,6 +7,7 @@
package main
import (
"context"
"crypto/tls"
"encoding/binary"
"fmt"
@@ -32,7 +33,6 @@ type replicationSender struct {
cert tls.Certificate // our certificate
allowedIDs []protocol.DeviceID
outbox chan ReplicationRecord
stop chan struct{}
}
func newReplicationSender(dst string, cert tls.Certificate, allowedIDs []protocol.DeviceID) *replicationSender {
@@ -41,11 +41,10 @@ func newReplicationSender(dst string, cert tls.Certificate, allowedIDs []protoco
cert: cert,
allowedIDs: allowedIDs,
outbox: make(chan ReplicationRecord, replicationOutboxSize),
stop: make(chan struct{}),
}
}
func (s *replicationSender) Serve() {
func (s *replicationSender) Serve(ctx context.Context) error {
// Sleep a little at startup. Peers often restart at the same time, and
// this avoid the service failing and entering backoff state
// unnecessarily, while also reducing the reconnect rate to something
@@ -62,7 +61,7 @@ func (s *replicationSender) Serve() {
conn, err := tls.Dial("tcp", s.dst, tlsCfg)
if err != nil {
log.Println("Replication connect:", err)
return
return err
}
defer func() {
conn.SetWriteDeadline(time.Now().Add(time.Second))
@@ -73,13 +72,13 @@ func (s *replicationSender) Serve() {
remoteID, err := deviceID(conn)
if err != nil {
log.Println("Replication connect:", err)
return
return err
}
// Verify it's in the set of allowed device IDs.
if !deviceIDIn(remoteID, s.allowedIDs) {
log.Println("Replication connect: unexpected device ID:", remoteID)
return
return err
}
heartBeatTicker := time.NewTicker(replicationHeartbeatInterval)
@@ -122,20 +121,16 @@ func (s *replicationSender) Serve() {
replicationSendsTotal.WithLabelValues("error").Inc()
log.Println("Replication write:", err)
// Yes, we are loosing the replication event here.
return
return err
}
replicationSendsTotal.WithLabelValues("success").Inc()
case <-s.stop:
return
case <-ctx.Done():
return nil
}
}
}
func (s *replicationSender) Stop() {
close(s.stop)
}
func (s *replicationSender) String() string {
return fmt.Sprintf("replicationSender(%q)", s.dst)
}
@@ -172,7 +167,6 @@ type replicationListener struct {
cert tls.Certificate
allowedIDs []protocol.DeviceID
db database
stop chan struct{}
}
func newReplicationListener(addr string, cert tls.Certificate, allowedIDs []protocol.DeviceID, db database) *replicationListener {
@@ -181,11 +175,10 @@ func newReplicationListener(addr string, cert tls.Certificate, allowedIDs []prot
cert: cert,
allowedIDs: allowedIDs,
db: db,
stop: make(chan struct{}),
}
}
func (l *replicationListener) Serve() {
func (l *replicationListener) Serve(ctx context.Context) error {
tlsCfg := &tls.Config{
Certificates: []tls.Certificate{l.cert},
ClientAuth: tls.RequestClientCert,
@@ -196,14 +189,14 @@ func (l *replicationListener) Serve() {
lst, err := tls.Listen("tcp", l.addr, tlsCfg)
if err != nil {
log.Println("Replication listen:", err)
return
return err
}
defer lst.Close()
for {
select {
case <-l.stop:
return
case <-ctx.Done():
return nil
default:
}
@@ -211,7 +204,7 @@ func (l *replicationListener) Serve() {
conn, err := lst.Accept()
if err != nil {
log.Println("Replication accept:", err)
return
return err
}
// Figure out the other side device ID
@@ -231,19 +224,15 @@ func (l *replicationListener) Serve() {
continue
}
go l.handle(conn)
go l.handle(ctx, conn)
}
}
func (l *replicationListener) Stop() {
close(l.stop)
}
func (l *replicationListener) String() string {
return fmt.Sprintf("replicationListener(%q)", l.addr)
}
func (l *replicationListener) handle(conn net.Conn) {
func (l *replicationListener) handle(ctx context.Context, conn net.Conn) {
defer func() {
conn.SetWriteDeadline(time.Now().Add(time.Second))
conn.Close()
@@ -253,7 +242,7 @@ func (l *replicationListener) handle(conn net.Conn) {
for {
select {
case <-l.stop:
case <-ctx.Done():
return
default:
}