Musique-server integration

This commit is contained in:
Robert Bendun 2022-12-09 16:05:25 +01:00
parent 5e67bf9a2f
commit 6bbb296bb2
6 changed files with 226 additions and 20 deletions

View File

@ -0,0 +1,81 @@
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package musique/http-server/src */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h>
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef size_t GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
#ifdef _MSC_VER
#include <complex.h>
typedef _Fcomplex GoComplex64;
typedef _Dcomplex GoComplex128;
#else
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
#endif
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern void ServerInit();
#ifdef __cplusplus
}
#endif

Binary file not shown.

View File

@ -6,9 +6,9 @@ import (
"log" "log"
"net" "net"
"os" "os"
"strings"
"sync" "sync"
"time" "time"
"strings"
) )
func scanError(scanResult []string, conn net.Conn) { func scanError(scanResult []string, conn net.Conn) {
@ -41,7 +41,7 @@ func remotef(host, command, format string, args ...interface{}) (int, error) {
if err != nil { if err != nil {
return 0, fmt.Errorf("remotef: parsing: %v", err) return 0, fmt.Errorf("remotef: parsing: %v", err)
} }
return parsedCount, nil return parsedCount, nil
} }
return 0, nil return 0, nil
@ -73,7 +73,7 @@ func timesync(hosts []string) []client {
id, host := id, host id, host := id, host
go func() { go func() {
defer wg.Done() defer wg.Done()
exchange := timeExchange{}; exchange := timeExchange{}
if exchange.estimateFor(host) { if exchange.estimateFor(host) {
responses <- client{exchange, id, host} responses <- client{exchange, id, host}
} }
@ -95,15 +95,16 @@ func timesync(hosts []string) []client {
const maxReactionTime = 300 const maxReactionTime = 300
func notifyAll(clients []client) { func notifyAll(clients []client) <-chan time.Time {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(len(clients)) wg.Add(len(clients))
startDeadline := time.After(maxReactionTime * time.Millisecond) startDeadline := time.After(maxReactionTime * time.Millisecond)
for _, client := range clients { for _, client := range clients {
client := client client := client
go func() { go func() {
startTime := maxReactionTime - (client.after - client.before) / 2 startTime := maxReactionTime - (client.after-client.before)/2
_, err := remotef(client.addr, fmt.Sprintf("start %d", startTime), "") _, err := remotef(client.addr, fmt.Sprintf("start %d", startTime), "")
if err != nil { if err != nil {
log.Printf("failed to notify %s: %v\n", client.addr, err) log.Printf("failed to notify %s: %v\n", client.addr, err)
@ -112,8 +113,7 @@ func notifyAll(clients []client) {
}() }()
} }
<-startDeadline return startDeadline
return
} }
func main() { func main() {
@ -129,7 +129,10 @@ func main() {
} }
go func(c net.Conn) { go func(c net.Conn) {
s := bufio.NewScanner(c) s := bufio.NewScanner(c)
var scanResult []string scanResult := []string{
"10.100.5.112:8081",
"10.100.5.44:8081",
}
var clients []client var clients []client
for s.Scan() { for s.Scan() {
resp := s.Text() resp := s.Text()
@ -171,7 +174,7 @@ func main() {
continue continue
} }
if resp == "notify" { if resp == "notify" {
notifyAll(clients) <-notifyAll(clients)
log.Println("Started #notify") log.Println("Started #notify")
continue continue
} }

View File

@ -2,26 +2,67 @@ package main
import ( import (
"C" "C"
"net"
"bufio"
"fmt" "fmt"
"time" "time"
"strings"
) )
var clients []client
var pinger chan struct{}
//export ServerInit //export ServerInit
func ServerInit() { func ServerInit() {
fmt.Println("Initializing server") // scanResult = scan()
scanResult := []string{
"10.100.5.112:8081",
"10.100.5.44:8081",
}
clients = timesync(scanResult)
pinger = make(chan struct{}, 100)
go func() {
l, err := net.Listen("tcp", ":8081")
if err != nil {
return
}
defer l.Close()
for {
conn, err := l.Accept()
if err != nil {
continue
}
go func(c net.Conn) {
defer c.Close()
s := bufio.NewScanner(c)
for s.Scan() {
response := s.Text()
if response == "time" {
fmt.Fprintln(conn, time.Now().UnixMilli())
continue
}
if strings.HasPrefix(response, "start") {
startTimeString := strings.TrimSpace(response[len("start"):])
startTime := int64(0)
fmt.Sscanf(startTimeString, "%d", &startTime)
time.Sleep(time.Duration(startTime) * time.Millisecond)
pinger <- struct{}{}
continue
}
}
}(conn)
}
}()
} }
//export ServerBeginProtocol //export ServerBeginProtocol
func ServerBeginProtocol() { func ServerBeginProtocol() {
protocol := []string{ self := notifyAll(clients)
"Make the plan", select {
"Execute the plan", case <- self:
"Expect the plan to go off the rails", case <- pinger:
"Throw away the plan",
}
for i, msg := range protocol {
fmt.Printf("%d. %s\n", i, msg)
time.Sleep(300 * time.Millisecond)
} }
} }

81
server/src/server.h Normal file
View File

@ -0,0 +1,81 @@
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package musique/http-server/src */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h>
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef size_t GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
#ifdef _MSC_VER
#include <complex.h>
typedef _Fcomplex GoComplex64;
typedef _Dcomplex GoComplex128;
#else
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
#endif
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern void ServerInit();
#ifdef __cplusplus
}
#endif

BIN
server/src/src Executable file

Binary file not shown.