Skip to content

Commit 023ebbc

Browse files
authored
feat: Add OnBeforeSend hook (#1325)
This adds an optional `OnBeforeSend` hook to plugin clients that choose to implement the interface. When implemented, the plugin client will receive a call before every message is sent, allowing it to modify the message, perform a side-effect, or return an error. This keeps the potentially general useful for all plugins, with the first use case being to check whether a row should be counted as premium or not in upcoming paid plugins.
1 parent c07c486 commit 023ebbc

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

internal/servers/plugin/v3/plugin.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,13 @@ func (s *Server) Sync(req *pb.Sync_Request, stream pb.Plugin_SyncServer) error {
130130
syncErr = fmt.Errorf("failed to sync records: %w", err)
131131
}
132132
}()
133-
133+
var err error
134134
for msg := range msgs {
135+
msg, err = s.Plugin.OnBeforeSend(ctx, msg)
136+
if err != nil {
137+
syncErr = fmt.Errorf("failed before sending message: %w", err)
138+
return syncErr
139+
}
135140
pbMsg := &pb.Sync_Response{}
136141
switch m := msg.(type) {
137142
case *message.SyncMigrateTable:

plugin/plugin.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,23 @@ func (p *Plugin) Version() string {
124124
return p.version
125125
}
126126

127+
type OnBeforeSender interface {
128+
OnBeforeSend(context.Context, message.SyncMessage) (message.SyncMessage, error)
129+
}
130+
131+
// OnBeforeSend gets called before every message is sent to the destination. A plugin client
132+
// that implements the OnBeforeSender interface will have this method called.
133+
func (p *Plugin) OnBeforeSend(ctx context.Context, msg message.SyncMessage) (message.SyncMessage, error) {
134+
// This method is called once for every message, so it is on the hot path, and we should be careful about its performance.
135+
// However, most recent versions of Go have optimized type assertions and type switches to be very fast, so
136+
// we use them here without expecting a significant impact on performance.
137+
// See: https://stackoverflow.com/questions/28024884/does-a-type-assertion-type-switch-have-bad-performance-is-slow-in-go
138+
if v, ok := p.client.(OnBeforeSender); ok {
139+
return v.OnBeforeSend(ctx, msg)
140+
}
141+
return msg, nil
142+
}
143+
127144
// IsStaticLinkingEnabled whether static linking is to be enabled
128145
func (p *Plugin) IsStaticLinkingEnabled() bool {
129146
return p.staticLinking

0 commit comments

Comments
 (0)