Skip to content

Commit

Permalink
perf(debugger): Implement our own sequence diagrams
Browse files Browse the repository at this point in the history
Calling `plantuml` is really slow (probably because it is java application and
java boot is slow), so this commit replaces that with our own sequence diagram
drawing code. It should be reasonable feature complete with what we had before,
but it should take significantly less time to compute the diagrams, and
therefore also boot the debugger.

The diagrams are drawn in a lazy fashion, where we only draw the diagram if it
is looked at. This might not really be needed since we draw them so fast, but I
already had the code for when I was trying to get `plantuml` to work that I
decided to keep it.

closes #66
  • Loading branch information
symbiont-daniel-gustafsson committed Feb 1, 2021
1 parent 8e6fbf6 commit cc4e1fd
Show file tree
Hide file tree
Showing 10 changed files with 572 additions and 73 deletions.
1 change: 0 additions & 1 deletion shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pkgs.mkShell {
python38
mypy

plantuml
git
nix
niv
Expand Down
6 changes: 3 additions & 3 deletions src/debugger/cmd/detsys-debug/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type DebugApplication struct {
testId lib.TestId
runId lib.RunId
heaps []map[string][]byte
diagrams [][]byte
diagrams *debugger.SequenceDiagrams
events []debugger.NetworkEvent
reactors []string
activeRow int // should probably be logic time
Expand Down Expand Up @@ -79,7 +79,7 @@ func (da *DebugApplication) redraw() {
messageView.Clear()
logView.Clear()
row := da.activeRow
fmt.Fprintf(w2, "%s", string(da.diagrams[row-1]))
fmt.Fprintf(w2, "%s", string(da.diagrams.At(row-1)))
reactor := da.reactors[da.activeReactor]
old := da.heaps[row-1][reactor]
new := da.heaps[min(row, len(da.heaps))][reactor]
Expand All @@ -101,7 +101,7 @@ func (da *DebugApplication) redraw() {
func MakeDebugApplication(testId lib.TestId, runId lib.RunId) *DebugApplication {
heaps := debugger.Heaps(testId, runId)
events := debugger.GetNetworkTrace(testId, runId)
diagrams := debugger.SequenceDiagrams(testId, runId)
diagrams := debugger.NewSequenceDiagrams(testId, runId)

reactors := make([]string, 0, len(heaps[0]))
for reactor := range heaps[0] {
Expand Down
3 changes: 1 addition & 2 deletions src/debugger/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ buildGoModule rec {

src = gitignoreSource ./.;
buildInputs = [ detsysLib ];
propagatedBuildInputs = [ plantuml ];

vendorSha256 = "19idzkfakvr58rs98ajsc9lnvrpjgn9z4h35ldgx5fdfja39nnzb";
vendorSha256 = "0ssxxfgckap99n5vfl3z1fjb2sc59wlf1h65l6jgir7zx7ndlzvr";

buildFlagsArray =
[ "-ldflags=-X main.version=${lib.commitIdFromGitRepo ./../../.git}" ];
Expand Down
2 changes: 2 additions & 0 deletions src/debugger/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ go 1.15
replace github.com/symbiont-io/detsys-testkit/src/lib => ../lib

require (
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
github.com/evanphx/json-patch v4.9.0+incompatible
github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591
github.com/mattn/go-sqlite3 v1.14.5
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce
github.com/pkg/errors v0.8.1 // indirect
github.com/rivo/tview v0.0.0-20201018122409-d551c850a743
github.com/sergi/go-diff v1.1.0 // indirect
github.com/symbiont-io/detsys-testkit/src/lib v0.0.0-00010101000000-000000000000
)
16 changes: 16 additions & 0 deletions src/debugger/go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591 h1:0WWUDZ1oxq7NxVyGo8M3KI5jbkiwNAdZFFzAdC68up4=
github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
Expand All @@ -15,14 +22,23 @@ github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/tview v0.0.0-20201018122409-d551c850a743 h1:9BBjVJTRxuYBeCAv9DFH2hSzY0ujLx5sxMg5D3K/Xeg=
github.com/rivo/tview v0.0.0-20201018122409-d551c850a743/go.mod h1:t7mcA3nlK9dxD1DMoz/DQRMWFMkGBUj6rJBM5VNfLFA=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7 h1:XtNJkfEjb4zR3q20BBBcYUykVOEMgZeIUOpBPfNYgxg=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
3 changes: 2 additions & 1 deletion src/debugger/internal/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ go_library(
"@com_github_evanphx_json_patch//:json-patch",
"@com_github_mattn_go_sqlite3//:go-sqlite3",
"@com_github_nsf_jsondiff//:jsondiff",
"@com_github_andreyvit_diff//:diff",
],
)

go_test(
name = "internal_test",
srcs = ["debugger_test.go"],
srcs = ["debugger_test.go" "sequence_test.go"],
embed = [":internal"],
deps = ["//src/lib"],
)
89 changes: 29 additions & 60 deletions src/debugger/internal/debugger.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ import (
jsonpatch "github.com/evanphx/json-patch"
_ "github.com/mattn/go-sqlite3"
"github.com/nsf/jsondiff"
"io/ioutil"
"os"
"os/exec"
"strings"
"time"

Expand Down Expand Up @@ -198,70 +195,42 @@ func colon(s string) string {
return strings.Replace(s, ":", "", -1)
}

func SequenceDiagrams(testId lib.TestId, runId lib.RunId) [][]byte {
tmpfile, err := ioutil.TempFile("", "sequence_diagram_*_000.txt")
if err != nil {
panic(err)
}
net := GetNetworkTrace(testId, runId)
for i := 0; i < len(net); i++ {
if _, err := tmpfile.Write([]byte("@startuml\n")); err != nil {
tmpfile.Close()
panic(err)
}
for j, event := range net {
var arrow string
if event.Dropped {
arrow = "-->"
} else {
arrow = "->"
}
var line string
if i == j {
line = fmt.Sprintf("%s %s %s : <<< %s >>>\n",
colon(event.From), arrow, colon(event.To), event.Message)
} else {
line = fmt.Sprintf("%s %s %s : %s\n",
colon(event.From), arrow, colon(event.To), event.Message)
}
if _, err := tmpfile.Write([]byte(line)); err != nil {
tmpfile.Close()
panic(err)
}
}
if _, err := tmpfile.Write([]byte("@enduml\n")); err != nil {
tmpfile.Close()
panic(err)
}
}
type SequenceDiagrams struct {
inner map[int][]byte
net []NetworkEvent
}

cmd := exec.Command("plantuml", "-tutxt", tmpfile.Name())
err = cmd.Run()
if err != nil {
panic(err)
func NewSequenceDiagrams(testId lib.TestId, runId lib.RunId) *SequenceDiagrams {
net := GetNetworkTrace(testId, runId)
return &SequenceDiagrams{
inner: make(map[int][]byte),
net: net,
}
}

base := strings.TrimSuffix(tmpfile.Name(), ".txt")
func (s *SequenceDiagrams) At(at int) []byte {
val, ok := s.inner[at]

diagrams := make([][]byte, len(net))
var file string
if ok {
return val
}

for i := 0; i < len(net); i++ {
if i == 0 {
file = base + ".utxt"
} else {
file = fmt.Sprintf("%s_%03d.utxt", base, i)
}
diagram, err := ioutil.ReadFile(file)
if err != nil {
panic(err)
}
diagrams[i] = []byte(diagram)
os.Remove(file)
arrows := make([]Arrow, 0, len(s.net))
for _, event := range s.net {
arrows = append(arrows, Arrow{
From: event.From,
To: event.To,
Message: event.Message,
Dropped: event.Dropped,
})
}
defer os.Remove(tmpfile.Name())
gen := DrawDiagram(arrows, DrawSettings{
MarkerSize: 3,
MarkAt: at,
})

return diagrams
s.inner[at] = gen
return gen
}

func GetLogMessages(testId lib.TestId, runId lib.RunId, reactor string, at int) [][]byte {
Expand Down
6 changes: 0 additions & 6 deletions src/debugger/internal/debugger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,3 @@ func TestHeaps(t *testing.T) {
heaps := Heaps(lib.TestId{1}, lib.RunId{0})
fmt.Printf("%v", heaps)
}

func TestSequenceDiagrams(t *testing.T) {
for _, diagram := range SequenceDiagrams(lib.TestId{1}, lib.RunId{0}) {
fmt.Printf("%s\n", string(diagram))
}
}
Loading

0 comments on commit cc4e1fd

Please sign in to comment.