From 4479fcf7f4323ed1abaf66980a7b10d2e0b3c7ab Mon Sep 17 00:00:00 2001 From: hoernschen Date: Fri, 27 Nov 2020 05:52:27 +0100 Subject: [PATCH] Masterthesis --- 1602853607 Baseline Measurement Windows.csv | 11 ----- config/config.go | 4 -- entities/event/eventController.go | 42 ++++++-------------- go.mod | 1 - main.go | 7 ---- sqlite.db | Bin 77824 -> 106496 bytes workloadGenerator.go | 20 ++++++++-- 7 files changed, 28 insertions(+), 57 deletions(-) delete mode 100644 1602853607 Baseline Measurement Windows.csv diff --git a/1602853607 Baseline Measurement Windows.csv b/1602853607 Baseline Measurement Windows.csv deleted file mode 100644 index bb48dda..0000000 --- a/1602853607 Baseline Measurement Windows.csv +++ /dev/null @@ -1,11 +0,0 @@ -Iteration,Start,End -1,1602853607,1602853727 -2,1602853727,1602853847 -3,1602853847,1602853967 -4,1602853967,1602854087 -5,1602854087,1602854207 -6,1602854207,1602854327 -7,1602854327,1602854447 -8,1602854447,1602854567 -9,1602854567,1602854687 -10,1602854687,1602854807 diff --git a/config/config.go b/config/config.go index abe58da..a5bc5e3 100644 --- a/config/config.go +++ b/config/config.go @@ -2,8 +2,6 @@ package config import ( "time" - - "github.com/lestrrat-go/backoff" ) var ServerName string = "Hoernschen's Matrix Server" @@ -25,8 +23,6 @@ var Signing bool var Encryption bool var HttpString string -var BackoffPolicy *backoff.Exponential - func SetDefaultParams() { Packetloss = 0.0 UnavailableTill = time.Now().Unix() diff --git a/entities/event/eventController.go b/entities/event/eventController.go index 9fde86d..d960652 100644 --- a/entities/event/eventController.go +++ b/entities/event/eventController.go @@ -2,7 +2,6 @@ package event import ( "bytes" - "context" "encoding/json" "errors" "fmt" @@ -17,9 +16,8 @@ import ( "git.nutfactory.org/hoernschen/Matrix/entities/user" "git.nutfactory.org/hoernschen/Matrix/utils" - //"github.com/cenkalti/backoff/v4" + "github.com/cenkalti/backoff/v4" "github.com/gorilla/mux" - "github.com/lestrrat-go/backoff" ) func New( @@ -178,16 +176,15 @@ func SendMessageHandler(w http.ResponseWriter, r *http.Request) { for _, server := range servers { if server != config.Homeserver { log.Printf("Send Transaction to %s", server) - /* - operation := func() error { - return SendTransaction(transaction, server, config.HttpString, config.AuthentificationCheck) - } - notify := func(err error, duration time.Duration) { - log.Printf("Error Sending Transaction, retrying in %ss: %s", duration/1000000000, err) - } - backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify) - */ - go retryTransaction(transaction, server, config.HttpString, config.AuthentificationCheck) + + operation := func() error { + return SendTransaction(transaction, server, config.HttpString, config.AuthentificationCheck) + } + notify := func(err error, duration time.Duration) { + log.Printf("Error Sending Transaction, retrying in %ss: %s", duration/1000000000, err) + } + backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify) + } } response := createEventResponse{ @@ -199,20 +196,6 @@ func SendMessageHandler(w http.ResponseWriter, r *http.Request) { } } -func retryTransaction(transactionToSend *Transaction, server string, httpString string, authCheck bool) (err error) { - b, cancel := config.BackoffPolicy.Start(context.Background()) - defer cancel() - - for backoff.Continue(b) { - err := SendTransaction(transactionToSend, server, httpString, authCheck) - if err == nil { - return nil - } - } - err = errors.New("Not able to send transaction") - return -} - func CreateStateEventHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") errResponse := utils.CheckRequest(r) @@ -294,14 +277,13 @@ func CreateStateEventHandler(w http.ResponseWriter, r *http.Request) { return } for _, server := range servers { - /*operation := func() error { + operation := func() error { return SendTransaction(transaction, server, config.HttpString, config.AuthentificationCheck) } notify := func(err error, duration time.Duration) { log.Printf("Error Sending Transaction, retrying in %ss: %s", duration/1000000000, err) } - go backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify)*/ - go retryTransaction(transaction, server, config.HttpString, config.AuthentificationCheck) + go backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify) } response := createEventResponse{ diff --git a/go.mod b/go.mod index 5043d3e..0e48f00 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,5 @@ go 1.14 require ( github.com/cenkalti/backoff/v4 v4.1.0 github.com/gorilla/mux v1.8.0 - github.com/lestrrat-go/backoff v1.0.0 github.com/mattn/go-sqlite3 v1.14.4 ) diff --git a/main.go b/main.go index 5ba2bdd..43a5603 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ import ( "log" "net/http" "os" - "time" "git.nutfactory.org/hoernschen/Matrix/config" "git.nutfactory.org/hoernschen/Matrix/entities/device" @@ -15,7 +14,6 @@ import ( "git.nutfactory.org/hoernschen/Matrix/entities/user" "git.nutfactory.org/hoernschen/Matrix/utils/database" "git.nutfactory.org/hoernschen/Matrix/utils/router" - "github.com/lestrrat-go/backoff" ) var keyPath = "./ssl.key" @@ -72,11 +70,6 @@ func main() { config.VerifyKeys = make(map[string]map[string][]byte) os.Remove("sqlite.db") - config.BackoffPolicy = backoff.NewExponential( - backoff.WithInterval(500*time.Millisecond), - backoff.WithMaxRetries(16), - ) - if err := database.InitDB("sqlite.db"); err != nil { log.Fatal(err) } diff --git a/sqlite.db b/sqlite.db index 46f09c40bd114763889bb24bea45a51642db08de..70ef887dca49676b3a9030ca69ab9eda5f37796a 100644 GIT binary patch literal 106496 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