Merge branch 'dev' into player-refactoring-phase-1
This commit is contained in:
commit
1524733f65
37 changed files with 297 additions and 238 deletions
2
.github/workflows/sourcemaps-reader.yaml
vendored
2
.github/workflows/sourcemaps-reader.yaml
vendored
|
|
@ -7,7 +7,7 @@ on:
|
|||
paths:
|
||||
- sourcemap-reader/**
|
||||
|
||||
name: Build and Deploy Chalice
|
||||
name: Build and Deploy sourcemap-reader
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ class JiraManager:
|
|||
|
||||
def get_issue_types(self):
|
||||
try:
|
||||
types = self._jira.issue_types()
|
||||
types = self._jira.project(self._config['JIRA_PROJECT_ID']).issueTypes
|
||||
except JIRAError as e:
|
||||
self.retries -= 1
|
||||
if (e.status_code // 100) == 4 and self.retries > 0:
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ func main() {
|
|||
log.Printf("Error while caching: %v", err)
|
||||
case <-tick:
|
||||
cacher.UpdateTimeouts()
|
||||
case msg := <-msgConsumer.Rebalanced():
|
||||
log.Println(msg)
|
||||
default:
|
||||
if !cacher.CanCache() {
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ func main() {
|
|||
os.Exit(0)
|
||||
case <-commitTick:
|
||||
commitDBUpdates()
|
||||
case msg := <-consumer.Rebalanced():
|
||||
log.Println(msg)
|
||||
default:
|
||||
// Handle new message from queue
|
||||
if err := consumer.ConsumeNext(); err != nil {
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ func main() {
|
|||
if err := consumer.CommitBack(intervals.EVENTS_BACK_COMMIT_GAP); err != nil {
|
||||
log.Printf("can't commit messages with offset: %s", err)
|
||||
}
|
||||
case msg := <-consumer.Rebalanced():
|
||||
log.Println(msg)
|
||||
default:
|
||||
if err := consumer.ConsumeNext(); err != nil {
|
||||
log.Fatalf("Error on consuming: %v", err)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ func main() {
|
|||
})
|
||||
producer.Flush(cfg.ProducerTimeout)
|
||||
consumer.Commit()
|
||||
case msg := <-consumer.Rebalanced():
|
||||
log.Println(msg)
|
||||
default:
|
||||
if err := consumer.ConsumeNext(); err != nil {
|
||||
log.Fatalf("Error on consuming: %v", err)
|
||||
|
|
|
|||
|
|
@ -14,14 +14,11 @@ import (
|
|||
"openreplay/backend/internal/storage"
|
||||
"openreplay/backend/pkg/messages"
|
||||
"openreplay/backend/pkg/monitoring"
|
||||
"openreplay/backend/pkg/pprof"
|
||||
"openreplay/backend/pkg/queue"
|
||||
"openreplay/backend/pkg/url/assets"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pprof.StartProfilingServer()
|
||||
|
||||
metrics := monitoring.New("sink")
|
||||
|
||||
log.SetFlags(log.LstdFlags | log.LUTC | log.Llongfile)
|
||||
|
|
@ -147,6 +144,15 @@ func main() {
|
|||
case <-tickInfo:
|
||||
counter.Print()
|
||||
log.Printf("writer: %s", writer.Info())
|
||||
case <-consumer.Rebalanced():
|
||||
s := time.Now()
|
||||
// Commit now to avoid duplicate reads
|
||||
if err := consumer.Commit(); err != nil {
|
||||
log.Printf("can't commit messages: %s", err)
|
||||
}
|
||||
// Sync all files
|
||||
writer.Sync()
|
||||
log.Printf("manual sync finished, dur: %d", time.Now().Sub(s).Milliseconds())
|
||||
default:
|
||||
err := consumer.ConsumeNext()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ func main() {
|
|||
os.Exit(0)
|
||||
case <-counterTick:
|
||||
go counter.Print()
|
||||
case msg := <-consumer.Rebalanced():
|
||||
log.Println(msg)
|
||||
default:
|
||||
err := consumer.ConsumeNext()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/aws/aws-sdk-go v1.44.98
|
||||
github.com/btcsuite/btcutil v1.0.2
|
||||
github.com/confluentinc/confluent-kafka-go v1.8.2
|
||||
github.com/elastic/go-elasticsearch/v7 v7.13.1
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
|
|
@ -26,9 +27,8 @@ require (
|
|||
go.opentelemetry.io/otel/exporters/prometheus v0.30.0
|
||||
go.opentelemetry.io/otel/metric v0.30.0
|
||||
go.opentelemetry.io/otel/sdk/metric v0.30.0
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c
|
||||
google.golang.org/api v0.81.0
|
||||
gopkg.in/confluentinc/confluent-kafka-go.v1 v1.8.2
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
@ -38,7 +38,6 @@ require (
|
|||
cloud.google.com/go/storage v1.14.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.0 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
|
|
@ -53,7 +52,6 @@ require (
|
|||
github.com/jackc/puddle v1.2.2-0.20220404125616-4e959849469a // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/klauspost/compress v1.15.7 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/paulmach/orb v0.7.1 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
|
|
@ -69,7 +67,7 @@ require (
|
|||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
|
|
|||
|
|
@ -115,12 +115,11 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.0 h1:d1k62oAuQVxgdMdiDQnpkABbtIWTBwXHpDcyGQUw5QQ=
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.0/go.mod h1:WDFs+KlhHITEoCzEfHSNgj5aP7vjajyYbZpvTEGs1sE=
|
||||
github.com/confluentinc/confluent-kafka-go v1.8.2 h1:PBdbvYpyOdFLehj8j+9ba7FL4c4Moxn79gy9cYKxG5E=
|
||||
github.com/confluentinc/confluent-kafka-go v1.8.2/go.mod h1:u2zNLny2xq+5rWeTQjFHbDzzNuba4P1vo31r9r4uAdg=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
@ -328,14 +327,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
|||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
|
|
@ -400,8 +397,6 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0
|
|||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
|
|
@ -566,8 +561,9 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
|||
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y=
|
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo=
|
||||
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
@ -679,8 +675,8 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -941,8 +937,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/confluentinc/confluent-kafka-go.v1 v1.8.2 h1:QAgN6OC0o7dwvyz+HML6GYm+0Pk54O91+oxGqJ/5z8I=
|
||||
gopkg.in/confluentinc/confluent-kafka-go.v1 v1.8.2/go.mod h1:ZdI3yfYmdNSLQPNCpO1y00EHyWaHG5EnQEyL/ntAegY=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
|
|
|||
|
|
@ -97,17 +97,21 @@ func (w *SessionWriter) Info() string {
|
|||
return fmt.Sprintf("%d sessions", w.meta.Count())
|
||||
}
|
||||
|
||||
func (w *SessionWriter) synchronizer() {
|
||||
tick := time.Tick(w.syncTimeout)
|
||||
for {
|
||||
select {
|
||||
case <-tick:
|
||||
func (w *SessionWriter) Sync() {
|
||||
w.sessions.Range(func(sid, lockObj any) bool {
|
||||
if err := w.sync(sid.(uint64)); err != nil {
|
||||
log.Printf("can't sync file descriptor: %s", err)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (w *SessionWriter) synchronizer() {
|
||||
tick := time.Tick(w.syncTimeout)
|
||||
for {
|
||||
select {
|
||||
case <-tick:
|
||||
w.Sync()
|
||||
case <-w.done:
|
||||
w.sessions.Range(func(sid, lockObj any) bool {
|
||||
if err := w.Close(sid.(uint64)); err != nil {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ type Consumer interface {
|
|||
CommitBack(gap int64) error
|
||||
Commit() error
|
||||
Close()
|
||||
Rebalanced() <-chan interface{}
|
||||
}
|
||||
|
||||
// Producer sends batches of session data to queue (redis or kafka)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ type Consumer struct {
|
|||
idsPending streamPendingIDsMap
|
||||
lastTs int64
|
||||
autoCommit bool
|
||||
event chan interface{}
|
||||
}
|
||||
|
||||
func NewConsumer(group string, streams []string, messageIterator messages.MessageIterator) *Consumer {
|
||||
|
|
@ -57,11 +58,16 @@ func NewConsumer(group string, streams []string, messageIterator messages.Messag
|
|||
group: group,
|
||||
autoCommit: true,
|
||||
idsPending: idsPending,
|
||||
event: make(chan interface{}, 4),
|
||||
}
|
||||
}
|
||||
|
||||
const READ_COUNT = 10
|
||||
|
||||
func (c *Consumer) Rebalanced() <-chan interface{} {
|
||||
return c.event
|
||||
}
|
||||
|
||||
func (c *Consumer) ConsumeNext() error {
|
||||
// MBTODO: read in go routine, send messages to channel
|
||||
res, err := c.redis.XReadGroup(&_redis.XReadGroupArgs{
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ package kafka
|
|||
|
||||
import (
|
||||
"log"
|
||||
"openreplay/backend/pkg/messages"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka"
|
||||
"openreplay/backend/pkg/env"
|
||||
"openreplay/backend/pkg/messages"
|
||||
|
||||
"github.com/confluentinc/confluent-kafka-go/kafka"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Message = kafka.Message
|
||||
|
|
@ -19,7 +19,7 @@ type Consumer struct {
|
|||
messageIterator messages.MessageIterator
|
||||
commitTicker *time.Ticker
|
||||
pollTimeout uint
|
||||
|
||||
events chan interface{}
|
||||
lastReceivedPrtTs map[int32]int64
|
||||
}
|
||||
|
||||
|
|
@ -61,6 +61,21 @@ func NewConsumer(
|
|||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
var commitTicker *time.Ticker
|
||||
if autoCommit {
|
||||
commitTicker = time.NewTicker(2 * time.Minute)
|
||||
}
|
||||
|
||||
consumer := &Consumer{
|
||||
c: c,
|
||||
messageIterator: messageIterator,
|
||||
commitTicker: commitTicker,
|
||||
pollTimeout: 200,
|
||||
events: make(chan interface{}, 4),
|
||||
lastReceivedPrtTs: make(map[int32]int64, 16),
|
||||
}
|
||||
|
||||
subREx := "^("
|
||||
for i, t := range topics {
|
||||
if i != 0 {
|
||||
|
|
@ -69,22 +84,27 @@ func NewConsumer(
|
|||
subREx += t
|
||||
}
|
||||
subREx += ")$"
|
||||
if err := c.Subscribe(subREx, nil); err != nil {
|
||||
if err := c.Subscribe(subREx, consumer.reBalanceCallback); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
var commitTicker *time.Ticker
|
||||
if autoCommit {
|
||||
commitTicker = time.NewTicker(2 * time.Minute)
|
||||
}
|
||||
return consumer
|
||||
}
|
||||
|
||||
return &Consumer{
|
||||
c: c,
|
||||
messageIterator: messageIterator,
|
||||
commitTicker: commitTicker,
|
||||
pollTimeout: 200,
|
||||
lastReceivedPrtTs: make(map[int32]int64),
|
||||
func (consumer *Consumer) reBalanceCallback(_ *kafka.Consumer, e kafka.Event) error {
|
||||
switch evt := e.(type) {
|
||||
case kafka.RevokedPartitions:
|
||||
// receive before re-balancing partitions; stop consuming messages and commit current state
|
||||
consumer.events <- evt.String()
|
||||
case kafka.AssignedPartitions:
|
||||
// receive after re-balancing partitions; continue consuming messages
|
||||
//consumer.events <- evt.String()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (consumer *Consumer) Rebalanced() <-chan interface{} {
|
||||
return consumer.events
|
||||
}
|
||||
|
||||
func (consumer *Consumer) Commit() error {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
package kafka
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka"
|
||||
"github.com/confluentinc/confluent-kafka-go/kafka"
|
||||
)
|
||||
|
||||
|
||||
func logPartitions(s string, prts []kafka.TopicPartition) {
|
||||
for _, p := range prts {
|
||||
s = fmt.Sprintf("%v | %v", s, p.Partition)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"gopkg.in/confluentinc/confluent-kafka-go.v1/kafka"
|
||||
"github.com/confluentinc/confluent-kafka-go/kafka"
|
||||
"openreplay/backend/pkg/env"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,4 +23,4 @@ MINIO_SECRET_KEY = ''
|
|||
|
||||
# APP and TRACKER VERSIONS
|
||||
VERSION = '1.9.0'
|
||||
TRACKER_VERSION = '4.1.7'
|
||||
TRACKER_VERSION = '4.1.9'
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ function AuditView(props) {
|
|||
]}
|
||||
defaultValue={order}
|
||||
plain
|
||||
onChange={({ value }) => auditStore.updateKey('order', value)}
|
||||
onChange={({ value }) => auditStore.updateKey('order', value.value)}
|
||||
/>
|
||||
</div>
|
||||
<AuditSearchField onChange={(value) => auditStore.updateKey('searchQuery', value) }/>
|
||||
|
|
|
|||
|
|
@ -2,11 +2,10 @@ import React, { useEffect } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { setAutoplayValues } from 'Duck/sessions';
|
||||
import { session as sessionRoute } from 'App/routes';
|
||||
import { Link, Icon, Toggler, Tooltip } from 'UI';
|
||||
import { Link, Icon, Tooltip } from 'UI';;
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import cn from 'classnames';
|
||||
import { fetchAutoplaySessions } from 'Duck/search';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
const PER_PAGE = 10;
|
||||
|
|
@ -14,12 +13,10 @@ const PER_PAGE = 10;
|
|||
interface Props extends RouteComponentProps {
|
||||
previousId: string;
|
||||
nextId: string;
|
||||
autoplay: boolean;
|
||||
defaultList: any;
|
||||
currentPage: number;
|
||||
total: number;
|
||||
setAutoplayValues?: () => void;
|
||||
toggleAutoplay?: () => void;
|
||||
latestRequestTime: any;
|
||||
sessionIds: any;
|
||||
fetchAutoplaySessions?: (page: number) => Promise<void>;
|
||||
|
|
@ -37,8 +34,6 @@ function Autoplay(props: Props) {
|
|||
params: { sessionId },
|
||||
},
|
||||
} = props;
|
||||
const { player, store } = React.useContext(PlayerContext)
|
||||
const { autoplay } = store.get()
|
||||
|
||||
const disabled = sessionIds.length === 0;
|
||||
|
||||
|
|
@ -57,14 +52,6 @@ function Autoplay(props: Props) {
|
|||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<div
|
||||
onClick={() => player.toggleAutoplay()}
|
||||
className="cursor-pointer flex items-center mr-2 hover:bg-gray-light-shade rounded-md p-2"
|
||||
>
|
||||
<Toggler name="sessionsLive" onChange={() => player.toggleAutoplay()} checked={autoplay} />
|
||||
<span className="ml-2 whitespace-nowrap">Auto-Play</span>
|
||||
</div>
|
||||
|
||||
<Tooltip
|
||||
placement="bottom"
|
||||
title={<div className="whitespace-nowrap">Play Previous Session</div>}
|
||||
|
|
@ -114,4 +101,4 @@ export default connect(
|
|||
latestRequestTime: state.getIn(['search', 'latestRequestTime']),
|
||||
}),
|
||||
{ setAutoplayValues, fetchAutoplaySessions }
|
||||
)(withRouter(observer(Autoplay)))
|
||||
)(withRouter(Autoplay))
|
||||
|
|
@ -18,7 +18,6 @@ const SelectedValue = ({ icon, text }) => {
|
|||
class IssueForm extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
const { projects, issueTypes } = this.props;
|
||||
|
||||
this.props.init({
|
||||
projectId: projects[0] ? projects[0].id : '',
|
||||
issueType: issueTypes[0] ? issueTypes[0].id : '',
|
||||
|
|
@ -27,8 +26,8 @@ class IssueForm extends React.PureComponent {
|
|||
|
||||
componentWillReceiveProps(newProps) {
|
||||
const { instance } = this.props;
|
||||
if (instance.projectId && newProps.instance.projectId != instance.projectId) {
|
||||
this.props.fetchMeta(instance.projectId).then(() => {
|
||||
if (newProps.instance.projectId && newProps.instance.projectId != instance.projectId) {
|
||||
this.props.fetchMeta(newProps.instance.projectId).then(() => {
|
||||
this.props.edit({ issueType: '', assignee: '', projectId: newProps.instance.projectId });
|
||||
});
|
||||
}
|
||||
|
|
@ -87,7 +86,7 @@ class IssueForm extends React.PureComponent {
|
|||
<Select
|
||||
name="projectId"
|
||||
options={projectOptions}
|
||||
// value={instance.projectId}
|
||||
defaultValue={instance.projectId}
|
||||
fluid
|
||||
onChange={this.writeOption}
|
||||
placeholder="Project"
|
||||
|
|
@ -100,7 +99,7 @@ class IssueForm extends React.PureComponent {
|
|||
name="issueType"
|
||||
labeled
|
||||
options={issueTypeOptions}
|
||||
value={instance.issueType}
|
||||
defaultValue={instance.issueType}
|
||||
fluid
|
||||
onChange={this.writeOption}
|
||||
placeholder="Select issue type"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Icon, Popover } from 'UI';
|
||||
import { Icon, Popover, Button } from 'UI';
|
||||
import IssuesModal from './IssuesModal';
|
||||
import { fetchProjects, fetchMeta } from 'Duck/assignments';
|
||||
import stl from './issues.module.css';
|
||||
|
|
@ -67,30 +67,27 @@ class Issues extends React.Component {
|
|||
const provider = issuesIntegration.provider;
|
||||
|
||||
return (
|
||||
<div className="relative h-full w-full p-3">
|
||||
<div className={stl.buttonWrapper}>
|
||||
<Popover
|
||||
onOpen={this.handleOpen}
|
||||
render={({ close }) => (
|
||||
<div>
|
||||
<IssuesModal
|
||||
provider={provider}
|
||||
sessionId={sessionId}
|
||||
closeHandler={close}
|
||||
/>
|
||||
<IssuesModal provider={provider} sessionId={sessionId} closeHandler={close} />
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="flex items-center"
|
||||
<div className="relative">
|
||||
<Button icon={`integrations/${provider === 'jira' ? 'jira' : 'github'}`} variant="text">
|
||||
Create Issue
|
||||
</Button>
|
||||
</div>
|
||||
{/* <div
|
||||
className="flex items-center cursor-pointer"
|
||||
disabled={!isModalDisplayed && (metaLoading || fetchIssuesLoading || projectsLoading)}
|
||||
>
|
||||
<Icon name={`integrations/${provider === 'jira' ? 'jira' : 'github'}`} size="16" />
|
||||
<span className="ml-2">Create Issue</span>
|
||||
</div>
|
||||
<span className="ml-2 whitespace-nowrap">Create Issue</span>
|
||||
</div> */}
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ function ReadNote(props: Props) {
|
|||
<Icon name="close" size={18} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xl py-3 overflow-y-scroll capitalize-first" style={{ maxHeight: 400 }}>
|
||||
<div className="text-xl py-3 overflow-y-auto capitalize-first" style={{ maxHeight: 400 }}>
|
||||
{props.note.message}
|
||||
</div>
|
||||
<div className="w-full">
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import cn from 'classnames';
|
||||
import { connect } from 'react-redux'
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import { Button, Link } from 'UI'
|
||||
import { session as sessionRoute, withSiteId } from 'App/routes'
|
||||
import { Button, Link, Icon } from 'UI';
|
||||
import { session as sessionRoute, withSiteId } from 'App/routes';
|
||||
import stl from './AutoplayTimer.module.css';
|
||||
import clsOv from './overlay.module.css';
|
||||
|
||||
|
|
@ -13,49 +13,55 @@ interface IProps extends RouteComponentProps {
|
|||
}
|
||||
|
||||
function AutoplayTimer({ nextId, siteId, history }: IProps) {
|
||||
let timer: NodeJS.Timer
|
||||
let timer: NodeJS.Timer;
|
||||
const [cancelled, setCancelled] = useState(false);
|
||||
const [counter, setCounter] = useState(5);
|
||||
|
||||
useEffect(() => {
|
||||
if(counter > 0) {
|
||||
if (counter > 0) {
|
||||
timer = setTimeout(() => {
|
||||
setCounter(counter - 1)
|
||||
}, 1000)
|
||||
setCounter(counter - 1);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
if (counter === 0) {
|
||||
history.push(withSiteId(sessionRoute(nextId), siteId))
|
||||
history.push(withSiteId(sessionRoute(nextId), siteId));
|
||||
}
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [counter])
|
||||
}, [counter]);
|
||||
|
||||
const cancel = () => {
|
||||
clearTimeout(timer)
|
||||
setCancelled(true)
|
||||
}
|
||||
clearTimeout(timer);
|
||||
setCancelled(true);
|
||||
};
|
||||
|
||||
if (cancelled)
|
||||
return null
|
||||
if (cancelled) return null;
|
||||
|
||||
return (
|
||||
<div className={ cn(clsOv.overlay, stl.overlayBg) } >
|
||||
<div className={cn(clsOv.overlay, stl.overlayBg)}>
|
||||
<div className="border p-6 shadow-lg bg-white rounded">
|
||||
<div className="py-4">Next recording will be played in {counter}s</div>
|
||||
<div className="flex items-center">
|
||||
<Button primary="outline" onClick={cancel}>Cancel</Button>
|
||||
<Button primary="outline" onClick={cancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<div className="px-3" />
|
||||
<Link to={ sessionRoute(nextId) } disabled={!nextId}>
|
||||
<Link to={sessionRoute(nextId)} disabled={!nextId}>
|
||||
<Button variant="primary">Play Now</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="mt-2 flex items-center color-gray-dark">
|
||||
Turn on/off auto-replay in <Icon name="ellipsis-v" className="mx-1" /> More options
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(connect(state => ({
|
||||
siteId: state.getIn([ 'site', 'siteId' ]),
|
||||
nextId: parseInt(state.getIn([ 'sessions', 'nextId' ])),
|
||||
}))(AutoplayTimer))
|
||||
export default withRouter(
|
||||
connect((state: any) => ({
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
nextId: parseInt(state.getIn(['sessions', 'nextId'])),
|
||||
}))(AutoplayTimer)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { useModal } from 'App/components/Modal';
|
|||
import BugReportModal from './BugReport/BugReportModal';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import AutoplayToggle from 'Shared/AutoplayToggle';
|
||||
|
||||
function SubHeader(props) {
|
||||
const { player, store } = React.useContext(PlayerContext)
|
||||
|
|
@ -74,39 +75,31 @@ function SubHeader(props) {
|
|||
className="ml-auto text-sm flex items-center color-gray-medium gap-2"
|
||||
style={{ width: 'max-content' }}
|
||||
>
|
||||
<Button icon="file-pdf" variant="text" onClick={showReportModal}>Create Bug Report</Button>
|
||||
<Button icon="file-pdf" variant="text" onClick={showReportModal}>
|
||||
Create Bug Report
|
||||
</Button>
|
||||
<NotePopup />
|
||||
<ItemMenu
|
||||
items={[
|
||||
{
|
||||
key: 2,
|
||||
component: props.jiraConfig && props.jiraConfig.token && (
|
||||
<Issues sessionId={props.sessionId} />
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
component: (
|
||||
<SharePopup
|
||||
entity="sessions"
|
||||
id={props.sessionId}
|
||||
showCopyLink={true}
|
||||
trigger={
|
||||
<div className="flex items-center h-full w-full">
|
||||
<Icon
|
||||
className="mr-2"
|
||||
disabled={props.disabled}
|
||||
name="share-alt"
|
||||
size="16"
|
||||
/>
|
||||
<span>Share</span>
|
||||
<div className="relative">
|
||||
<Button icon="share-alt" variant="text" className="relative">
|
||||
Share
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
),
|
||||
<ItemMenu
|
||||
items={[
|
||||
{
|
||||
key: 1,
|
||||
component: <AutoplayToggle />,
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
key: 2,
|
||||
component: <Bookmark noMargin sessionId={props.sessionId} />,
|
||||
},
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Icon } from 'UI';
|
||||
import { Icon, Button } from 'UI';
|
||||
import styles from './menu.module.css';
|
||||
import cn from 'classnames';
|
||||
import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv';
|
||||
|
|
@ -32,8 +32,8 @@ export default class ItemMenu extends React.PureComponent<Props> {
|
|||
};
|
||||
|
||||
closeMenu = () => {
|
||||
this.setState({ displayed: false })
|
||||
}
|
||||
this.setState({ displayed: false });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { items } = this.props;
|
||||
|
|
@ -42,23 +42,9 @@ export default class ItemMenu extends React.PureComponent<Props> {
|
|||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<OutsideClickDetectingDiv onClickOutside={this.closeMenu}>
|
||||
<div
|
||||
onClick={this.toggleMenu}
|
||||
className={cn(
|
||||
'flex items-center cursor-pointer select-none',
|
||||
'rounded p-2', displayed ? 'bg-gray-light' : 'hover:bg-gray-light-shade'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cn('rounded-full flex items-center justify-center', {
|
||||
'bg-gray-light': displayed,
|
||||
})}
|
||||
role="button"
|
||||
>
|
||||
<Icon name="ellipsis-v" size="16" />
|
||||
</div>
|
||||
<span className={'mr-1 text-disabled-text'}>More</span>
|
||||
</div>
|
||||
<Button variant="text" icon="ellipsis-v" onClick={this.toggleMenu}>
|
||||
More
|
||||
</Button>
|
||||
<div className={cn(styles.menu, styles.menuDim)} data-displayed={displayed}>
|
||||
{items.map((item) =>
|
||||
item.component ? (
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import stl from './signup.module.css'
|
|||
import { signup } from 'Duck/user';
|
||||
import { connect } from 'react-redux'
|
||||
import Select from 'Shared/Select'
|
||||
import { SITE_ID_STORAGE_KEY } from 'App/constants/storageKeys';
|
||||
|
||||
const LOGIN_ROUTE = login()
|
||||
const recaptchaRef = React.createRef()
|
||||
|
|
@ -41,9 +42,9 @@ export default class SignupForm extends React.Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
handleSubmit = (token) => {
|
||||
const { tenantId, fullname, password, email, projectName, organizationName, auth } = this.state;
|
||||
localStorage.removeItem(SITE_ID_STORAGE_KEY)
|
||||
this.props.signup({ tenantId, fullname, password, email, projectName, organizationName, auth, 'g-recaptcha-response': token })
|
||||
this.setState({ reload: true })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import { Controls as PlayerControls, connectPlayer } from 'Player';
|
||||
import { Toggler } from 'UI';
|
||||
|
||||
interface Props {
|
||||
toggleAutoplay: () => void;
|
||||
autoplay: boolean;
|
||||
}
|
||||
function AutoplayToggle(props: Props) {
|
||||
const { autoplay } = props;
|
||||
return (
|
||||
<div
|
||||
onClick={props.toggleAutoplay}
|
||||
className="cursor-pointer flex items-center mr-2 hover:bg-gray-light-shade rounded-md p-2"
|
||||
>
|
||||
<Toggler name="sessionsLive" onChange={props.toggleAutoplay} checked={autoplay} />
|
||||
<span className="ml-2 whitespace-nowrap">Auto-Play</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default connectPlayer(
|
||||
(state: any) => ({
|
||||
autoplay: state.autoplay,
|
||||
}),
|
||||
{
|
||||
toggleAutoplay: PlayerControls.toggleAutoplay,
|
||||
}
|
||||
)(AutoplayToggle);
|
||||
1
frontend/app/components/shared/AutoplayToggle/index.ts
Normal file
1
frontend/app/components/shared/AutoplayToggle/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export { default } from './AutoplayToggle';
|
||||
|
|
@ -149,7 +149,7 @@ function ConsolePanel() {
|
|||
)}
|
||||
</CellMeasurer>
|
||||
</React.Fragment>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -180,7 +180,6 @@ function NetworkPanel() {
|
|||
const onTabClick = (activeTab: typeof TAP_KEYS[number]) => devTools.update(INDEX_KEY, { activeTab })
|
||||
const onFilterChange = ({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => devTools.update(INDEX_KEY, { filter: value })
|
||||
|
||||
|
||||
// AutoScroll
|
||||
const countNow = fetchListNow.length + resourceListNow.length - intersectedCount
|
||||
const [
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ function StackEventPanel() {
|
|||
|
||||
const onTabClick = (activeTab: typeof TAB_KEYS[number]) => devTools.update(INDEX_KEY, { activeTab })
|
||||
const onFilterChange = ({ target: { value } }: React.ChangeEvent<HTMLInputElement>) => devTools.update(INDEX_KEY, { filter: value })
|
||||
|
||||
const tabs = useMemo(() =>
|
||||
TABS.filter(({ key }) => key === ALL || list.some(({ source }) => key === source)),
|
||||
[ list.length ],
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export default class SharePopup extends React.PureComponent {
|
|||
</div>
|
||||
)}
|
||||
>
|
||||
<div className="p-3 w-full">{trigger}</div>
|
||||
{trigger}
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ const Popover = ({ children, render, placement, onOpen = () => {} }: Props) => {
|
|||
{open && (
|
||||
<FloatingFocusManager
|
||||
context={context}
|
||||
modal={false}
|
||||
modal={true}
|
||||
order={['reference', 'content']}
|
||||
returnFocus={false}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ export const DURATION_FILTER = "__$session-durationFilter$__"
|
|||
export const SESSION_FILTER = "__$session-filter$__"
|
||||
export const GLOBAL_DESTINATION_PATH = "__$global-destinationPath$__"
|
||||
export const GLOBAL_HAS_NO_RECORDINGS = "__$global-hasNoRecordings$__"
|
||||
export const SITE_ID_STORAGE_KEY = "__$user-siteId$__"
|
||||
|
|
@ -15,14 +15,12 @@ import {
|
|||
createEdit,
|
||||
createRemove,
|
||||
createUpdate,
|
||||
createSave,
|
||||
saveType,
|
||||
} from './funcTools/crud';
|
||||
import { createRequestReducer } from './funcTools/request';
|
||||
import { Map, List, fromJS } from "immutable";
|
||||
import { GLOBAL_HAS_NO_RECORDINGS } from 'App/constants/storageKeys';
|
||||
import { GLOBAL_HAS_NO_RECORDINGS, SITE_ID_STORAGE_KEY } from 'App/constants/storageKeys';
|
||||
|
||||
const SITE_ID_STORAGE_KEY = "__$user-siteId$__";
|
||||
const storedSiteId = localStorage.getItem(SITE_ID_STORAGE_KEY);
|
||||
|
||||
const name = 'project';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<svg viewBox="0 0 29 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg viewBox="0 0 29 19" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.7" d="M11.6355 2.9045C10.8963 1.75328 9.80334 0.873101 8.521 0.396241C7.23867 -0.0806184 5.83621 -0.128393 4.5244 0.260101C3.21259 0.648595 2.06231 1.45237 1.24645 2.55061C0.430585 3.64885 -0.00678382 4.98223 7.95597e-05 6.35034C0.00076002 7.48328 0.305669 8.59524 0.882952 9.57006C1.46024 10.5449 2.28871 11.3468 3.28182 11.892C4.27493 12.4372 5.39624 12.7058 6.52859 12.6695C7.66095 12.6333 8.76279 12.2937 9.71903 11.6861C9.22188 13.1623 8.29591 14.7372 6.77033 16.316C6.47844 16.6179 6.31846 17.0234 6.32558 17.4433C6.3327 17.8632 6.50633 18.2631 6.80828 18.555C7.11022 18.8469 7.51575 19.0069 7.93566 18.9997C8.35556 18.9926 8.75543 18.819 9.04731 18.517C14.6867 12.6728 13.9542 6.31998 11.6355 2.91209V2.9045ZM26.8154 2.9045C26.0762 1.75328 24.9833 0.873101 23.7009 0.396241C22.4186 -0.0806184 21.0161 -0.128393 19.7043 0.260101C18.3925 0.648595 17.2422 1.45237 16.4264 2.55061C15.6105 3.64885 15.1731 4.98223 15.18 6.35034C15.1807 7.48328 15.4856 8.59524 16.0629 9.57006C16.6402 10.5449 17.4686 11.3468 18.4617 11.892C19.4549 12.4372 20.5762 12.7058 21.7085 12.6695C22.8409 12.6333 23.9427 12.2937 24.899 11.6861C24.4018 13.1623 23.4758 14.7372 21.9503 16.316C21.6584 16.6179 21.4984 17.0234 21.5055 17.4433C21.5126 17.8632 21.6863 18.2631 21.9882 18.555C22.2901 18.8469 22.6957 19.0069 23.1156 18.9997C23.5355 18.9926 23.9354 18.819 24.2272 18.517C29.8666 12.6728 29.1342 6.31998 26.8154 2.91209V2.9045Z" />
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
|
@ -19,9 +19,7 @@ version="v1.9.0"
|
|||
usr=`whoami`
|
||||
|
||||
# Installing k3s
|
||||
[[ x$SKIP_K8S_INSTALL == "xtrue" ]] && {
|
||||
info "Skipping Kuberntes installation"
|
||||
} || {
|
||||
function install_k8s{
|
||||
curl -sL https://get.k3s.io | sudo K3S_KUBECONFIG_MODE="644" INSTALL_K3S_VERSION='v1.22.8+k3s1' INSTALL_K3S_EXEC="--no-deploy=traefik" sh -
|
||||
[[ -d ~/.kube ]] || mkdir ~/.kube
|
||||
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
|
||||
|
|
@ -29,42 +27,42 @@ usr=`whoami`
|
|||
sudo chown -R $usr ~/.kube/config
|
||||
}
|
||||
|
||||
[[ x$SKIP_K8S_TOOLS == "xtrue" ]] && {
|
||||
info "Skipping Kuberntes installation"
|
||||
} || {
|
||||
function install_tools(){
|
||||
## installing kubectl
|
||||
which kubectl &> /dev/null || {
|
||||
info "kubectl not installed. Installing it..."
|
||||
sudo curl -SsL https://dl.k8s.io/release/v1.20.0/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl ; sudo chmod +x /usr/local/bin/kubectl
|
||||
}
|
||||
|
||||
## Installing GH package manager
|
||||
which eget &> /dev/null || {
|
||||
local version="1.3.0"
|
||||
info "eget not installed. Installing it..."
|
||||
curl -SsL https://github.com/zyedidia/eget/releases/download/v$version/eget-1.3.0-linux_amd64.tar.gz -o /tmp/eget.tar.gz
|
||||
cd /tmp
|
||||
tar -xf eget.tar.gz
|
||||
sudo mv eget-$version-linux_amd64/eget /usr/local/bin/eget
|
||||
sudo chmod +x /usr/local/bin/eget
|
||||
cd -
|
||||
}
|
||||
|
||||
## installing stern
|
||||
which stern &> /dev/null || {
|
||||
info "stern not installed. installing..."
|
||||
sudo curl -SsL https://github.com/derdanne/stern/releases/download/2.1.16/stern_linux_amd64 -o /usr/local/bin/stern ; sudo chmod +x /usr/local/bin/stern
|
||||
sudo eget --to /usr/local/bin stern/stern
|
||||
}
|
||||
|
||||
## installing k9s
|
||||
which k9s &> /dev/null || {
|
||||
info "k9s not installed. Installing it..."
|
||||
sudo curl -SsL https://github.com/derailed/k9s/releases/download/v0.24.2/k9s_Linux_x86_64.tar.gz -o /tmp/k9s.tar.gz
|
||||
cd /tmp
|
||||
tar -xf k9s.tar.gz
|
||||
sudo mv k9s /usr/local/bin/k9s
|
||||
sudo chmod +x /usr/local/bin/k9s
|
||||
cd -
|
||||
sudo eget --to /usr/local/bin derailed/k9s
|
||||
}
|
||||
|
||||
## installing helm
|
||||
which helm &> /dev/null
|
||||
if [[ $? -ne 0 ]]; then
|
||||
which helm &> /dev/null || {
|
||||
info "helm not installed. Installing it..."
|
||||
curl -ssl https://get.helm.sh/helm-v3.10.2-linux-amd64.tar.gz -o /tmp/helm.tar.gz
|
||||
tar -xf /tmp/helm.tar.gz
|
||||
chmod +x linux-amd64/helm
|
||||
sudo cp linux-amd64/helm /usr/local/bin/helm
|
||||
rm -rf linux-amd64/helm /tmp/helm.tar.gz
|
||||
fi
|
||||
sudo eget --to /usr/local/bin https://get.helm.sh/helm-v3.10.2-linux-amd64.tar.gz -f helm
|
||||
}
|
||||
}
|
||||
|
||||
sleep 10
|
||||
|
|
@ -79,10 +77,6 @@ randomPass() {
|
|||
|
||||
## Prepping the infra
|
||||
|
||||
[[ -z $DOMAIN_NAME ]] && {
|
||||
fatal 'DOMAIN_NAME variable is empty. Rerun the script `DOMAIN_NAME=openreplay.mycomp.org bash init.sh `'
|
||||
}
|
||||
|
||||
# Mac os doesn't have gnu sed, which will cause compatibility issues.
|
||||
# This wrapper will help to check the sed, and use the correct version="v1.9.0"
|
||||
# Ref: https://stackoverflow.com/questions/37639496/how-can-i-check-the-version="v1.9.0"
|
||||
|
|
@ -102,21 +96,52 @@ function sed_i_wrapper(){
|
|||
fi
|
||||
}
|
||||
|
||||
info "Creating dynamic passwords"
|
||||
sed_i_wrapper -i "s/postgresqlPassword: \"changeMePassword\"/postgresqlPassword: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/accessKey: \"changeMeMinioAccessKey\"/accessKey: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/secretKey: \"changeMeMinioPassword\"/secretKey: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/jwt_secret: \"SetARandomStringHere\"/jwt_secret: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/assistKey: \"SetARandomStringHere\"/assistKey: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/assistJWTSecret: \"SetARandomStringHere\"/assistJWTSecret: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/domainName: \"\"/domainName: \"${DOMAIN_NAME}\"/g" vars.yaml
|
||||
function create_passwords() {
|
||||
[[ -z $DOMAIN_NAME ]] && {
|
||||
fatal 'DOMAIN_NAME variable is empty. Rerun the script `DOMAIN_NAME=openreplay.mycomp.org bash init.sh `'
|
||||
}
|
||||
|
||||
info "Setting proper permission for shared folder"
|
||||
sudo mkdir -p /openreplay/storage/nfs
|
||||
sudo chown -R 1001:1001 /openreplay/storage/nfs
|
||||
info "Creating dynamic passwords"
|
||||
sed_i_wrapper -i "s/postgresqlPassword: \"changeMePassword\"/postgresqlPassword: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/accessKey: \"changeMeMinioAccessKey\"/accessKey: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/secretKey: \"changeMeMinioPassword\"/secretKey: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/jwt_secret: \"SetARandomStringHere\"/jwt_secret: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/assistKey: \"SetARandomStringHere\"/assistKey: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/assistJWTSecret: \"SetARandomStringHere\"/assistJWTSecret: \"$(randomPass)\"/g" vars.yaml
|
||||
sed_i_wrapper -i "s/domainName: \"\"/domainName: \"${DOMAIN_NAME}\"/g" vars.yaml
|
||||
}
|
||||
|
||||
|
||||
function set_permissions() {
|
||||
info "Setting proper permission for shared folder"
|
||||
sudo mkdir -p /openreplay/storage/nfs
|
||||
sudo chown -R 1001:1001 /openreplay/storage/nfs
|
||||
}
|
||||
|
||||
## Installing OpenReplay
|
||||
info "installing databases"
|
||||
helm upgrade --install databases ./databases -n db --create-namespace --wait -f ./vars.yaml --atomic
|
||||
info "installing application"
|
||||
helm upgrade --install openreplay ./openreplay -n app --create-namespace --wait -f ./vars.yaml --atomic
|
||||
function install_openreplay() {
|
||||
info "installing databases"
|
||||
helm upgrade --install databases ./databases -n db --create-namespace --wait -f ./vars.yaml --atomic
|
||||
info "installing application"
|
||||
helm upgrade --install openreplay ./openreplay -n app --create-namespace --wait -f ./vars.yaml --atomic
|
||||
}
|
||||
|
||||
function main(){
|
||||
[[ x$SKIP_K8S_INSTALL == "x1" ]] && {
|
||||
info "Skipping Kuberntes installation"
|
||||
} || {
|
||||
install_k8s
|
||||
}
|
||||
[[ x$SKIP_K8S_TOOLS == "x1" ]] && {
|
||||
info "Skipping Kuberntes tools installation"
|
||||
} || {
|
||||
install_tools
|
||||
}
|
||||
create_passwords
|
||||
set_permissions
|
||||
[[ x$SKIP_OR_INSTALL == "x1" ]] && {
|
||||
info "Skipping OpenReplay installation"
|
||||
} || {
|
||||
install_openreplay
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue