-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
110 lines (85 loc) · 2.18 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"encoding/json"
"io/ioutil"
"os"
"time"
i "github.com/savalin/example/internal"
)
// PROBLEM:
// The app calculates all shortest paths and destroys data in loop (by same dataset loaded from json ~1Mb).
// Using docker limits memory=10Gb and memory-swap=10Gb we faced OOM killing after a few iterations.
//
// reproduced using configuration:
// Makefile (for docker container build):
// - MEM_LIMIT=10Gb
// - MEM_SWAP=10Gb
// Go version:
// - >=go1.13
// Docker:
// - Server: Docker Engine - Community v19.03.5
// - Client: Docker Engine - Community v19.03.5
// Reproducible on Linux (tested on 5.4/5.4 kernels) and MacOS (tested on Catalina)
const edgesLimit = 9000 // please don't change this value. It's 'optimal' for success reproducing
var (
current i.Loader
old i.Loader
)
func main() {
var edges, err = readEdgesFile()
if err != nil {
panic(err)
}
i.PrintMemUsage()
var n = 1
for {
i.Log("loading graph: %d time", n)
start := time.Now()
l := i.NewLoader(edgesLimit)
l.Load(edges)
i.PrintMemUsage()
// some 'old' pointer to previous graph version
old = current
//doFakeUsage(old)
// set new current graph
current = l
//doFakeUsage(current)
// remove old pointer after all previous graph consumers graceful termination
old = nil
//// TRY TO FREE HEAP SYS MANUALLY
//t := time.Now()
//debug.FreeOSMemory()
//i.Log("after debug.FreeOSMemory() (%v):", time.Since(t))
//i.PrintMemUsage()
i.Log("time spent for #%d iteration: %v\n", n, time.Since(start))
n++
//time.Sleep(time.Minute * 5)
}
}
func readEdgesFile() ([]i.Edge, error) {
var file, err = os.Open("edges.json")
if err != nil {
return nil, err
}
defer file.Close()
var b []byte
if b, err = ioutil.ReadAll(file); err != nil {
return nil, err
}
var edges []i.Edge
if err = json.Unmarshal(b, &edges); err != nil {
return nil, err
}
i.Log("JSON parsed! %d edges found (data size: %d Mb)", len(edges), len(b)/1024/1024)
return edges, nil
}
func doFakeUsage(l i.Loader) {
if l == nil {
return
}
var weight float64
for k:=0; k<100;k++ {
_,weight = l.RoutesByAllShortest(11, 12915)
}
i.Log("graph fake usage passed. %f", weight)
}