-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf: add mcache #46
perf: add mcache #46
Conversation
Codecov ReportAttention: Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
|
98fcbc1
to
10fd2c5
Compare
3889bab
to
fdd484d
Compare
bbfc603
to
6b0a054
Compare
7f89329
to
fe38e83
Compare
db/dao/dao.go
Outdated
if e := mcache.Invalidate(ctx, key); e != nil { | ||
dao.log.Warnf("failed to invalidate mcache: key=%s, %v", key, err) | ||
} | ||
dao.publishEvent(eventbus.EventInvalidation, map[string]interface{}{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use go routine to publish if not care returning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM.
app/app.go
Outdated
app.bus = eventbus.NewDatabaseEventBus(cfg.DatabaseConfig.GetDSN(), app.log) | ||
app.bus.Subscribe(eventbus.EventInvalidation, func(data []byte) { | ||
maps := make(map[string]interface{}) | ||
if err := json.Unmarshal(data, &maps); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declare subscribe handlers somewhere else, keep app init code clean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM. Updated.
config/database.go
Outdated
) | ||
return sql.Open("postgres", dsn) | ||
func (cfg DatabaseConfig) GetDSN() string { | ||
dsn := cfg.DSN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dsn := cfg.DSN | |
dsn := cfg.dsn |
config/database.go
Outdated
cfg.Port, | ||
cfg.Database, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
cfg.dsn = dsn | |
} |
config/database.go
Outdated
"fmt" | ||
) | ||
|
||
type DatabaseConfig struct { | ||
DSN string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DSN string | |
dsn string |
already have GetDSN()
method, should keep DSN
private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to add a new configuration field for the database section. For example:
database:
dsn: postgres://username:[email protected]:5432/webhookx?sslmode=disable
...
The dsn
will have the highest priority compared the the rest of all (username, password, etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted. (will be done on another PR)
eventbus/eventbus.go
Outdated
handler(payload.Data) | ||
} | ||
} | ||
case <-time.After(90 * time.Second): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DO NOT USE time.After
in for select, it will cause memory leak, problem still exist in go 1.22
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think timer.After
does not cause permanent leak, because GC will capture it when the underlying timer expires.
I replaced it by time.NewTimer()
for the efficiency perspective.
|
||
var defaultOpts LoadOptions | ||
|
||
func Load[T any](ctx context.Context, key string, opts *LoadOptions, cb Callback[T], id string) (*T, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As opts could be nil, use ... Option
chain to override defaultOpts for better experience.
for example:
func Load[T any](ctx context.Context, key string, cb Callback[T], id string, opts ...Option) (*T, error) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding ... Option
at the end of the function arguments make things a bit complex. I prefer to use an Options struct here.
Co-authored-by: webhookx-x <[email protected]> Signed-off-by: Yusheng Li <[email protected]>
The eventbus can also be used for event router rebuild when source get changed. |
Summary
Add MCache(multiple levels cache) to improve performance.
MCache Implementations
The MCache uses LRU as the L1 cache and redis as the L2 cache. To invalidate the L1 cache of different WebhookX nodes, it uses Notify / Listen to broadcast events.