Skip to content

Commit 786b9fc

Browse files
committed
Merge branch 'main' into CBG-4412
2 parents 1e8d8ef + ea954fd commit 786b9fc

File tree

4 files changed

+316
-182
lines changed

4 files changed

+316
-182
lines changed

channels/sync_runner.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,10 @@ type SyncRunner struct {
116116
expiry *uint32 // document expiry (in seconds) specified via expiry() callback
117117
}
118118

119-
func NewSyncRunner(ctx context.Context, funcSource string, timeout time.Duration) (*SyncRunner, error) {
119+
func NewSyncRunnerWithLogging(ctx context.Context, funcSource string, timeout time.Duration, errorLogFunc, infoLogFunc func(string)) (*SyncRunner, error) {
120120
funcSource = wrappedFuncSource(funcSource)
121121
runner := &SyncRunner{}
122-
err := runner.InitWithLogging(funcSource, timeout,
123-
func(s string) { base.ErrorfCtx(ctx, base.KeyJavascript.String()+": Sync %s", base.UD(s)) },
124-
func(s string) { base.InfofCtx(ctx, base.KeyJavascript, "Sync %s", base.UD(s)) })
122+
err := runner.InitWithLogging(funcSource, timeout, errorLogFunc, infoLogFunc)
125123
if err != nil {
126124
return nil, err
127125
}
@@ -212,6 +210,12 @@ func NewSyncRunner(ctx context.Context, funcSource string, timeout time.Duration
212210
return runner, nil
213211
}
214212

213+
func NewSyncRunner(ctx context.Context, funcSource string, timeout time.Duration) (*SyncRunner, error) {
214+
errorLogFunc := func(s string) { base.ErrorfCtx(ctx, base.KeyJavascript.String()+": Sync %s", base.UD(s)) }
215+
infoLogFunc := func(s string) { base.InfofCtx(ctx, base.KeyJavascript, "Sync %s", base.UD(s)) }
216+
return NewSyncRunnerWithLogging(ctx, funcSource, timeout, errorLogFunc, infoLogFunc)
217+
}
218+
215219
func (runner *SyncRunner) SetFunction(funcSource string) (bool, error) {
216220
funcSource = wrappedFuncSource(funcSource)
217221
return runner.JSRunner.SetFunction(funcSource)

db/crud.go

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,8 +1697,7 @@ func (db *DatabaseCollectionWithUser) PutExistingRevWithBody(ctx context.Context
16971697
// SyncFnDryrun Runs the given document body through a sync function and returns expiry, channels doc was placed in,
16981698
// access map for users, roles, handler errors and sync fn exceptions.
16991699
// If syncFn is provided, it will be used instead of the one configured on the database.
1700-
func (db *DatabaseCollectionWithUser) SyncFnDryrun(ctx context.Context, newDoc, oldDoc *Document, syncFn string) (*channels.ChannelMapperOutput, error) {
1701-
1700+
func (db *DatabaseCollectionWithUser) SyncFnDryrun(ctx context.Context, newDoc, oldDoc *Document, syncFn string, errorLogFunc, infoLogFunc func(string)) (*channels.ChannelMapperOutput, error) {
17021701
mutableBody, metaMap, _, err := db.prepareSyncFn(oldDoc, newDoc)
17031702
if err != nil {
17041703
base.InfofCtx(ctx, base.KeyDiagnostic, "Failed to prepare to run sync function: %v", err)
@@ -1709,28 +1708,30 @@ func (db *DatabaseCollectionWithUser) SyncFnDryrun(ctx context.Context, newDoc,
17091708
if err != nil {
17101709
return nil, err
17111710
}
1712-
var output *channels.ChannelMapperOutput
1713-
var syncErr error
1711+
1712+
// fetch configured sync function if one is not provided
17141713
if syncFn == "" {
1715-
output, err = db.ChannelMapper.MapToChannelsAndAccess(ctx, mutableBody, string(oldDoc._rawBody), metaMap, syncOptions)
1716-
if err != nil {
1717-
return nil, &base.SyncFnDryRunError{Err: err}
1718-
}
1719-
} else {
1720-
jsTimeout := time.Duration(base.DefaultJavascriptTimeoutSecs) * time.Second
1721-
syncRunner, err := channels.NewSyncRunner(ctx, syncFn, jsTimeout)
1722-
if err != nil {
1723-
return nil, fmt.Errorf("failed to create sync runner: %v", err)
1714+
if db.ChannelMapper != nil {
1715+
syncFn = db.ChannelMapper.Function()
1716+
} else {
1717+
scopeAndCollectionName := db.ScopeAndCollectionName()
1718+
syncFn = channels.GetDefaultSyncFunction(scopeAndCollectionName.Scope, scopeAndCollectionName.Collection)
17241719
}
1725-
jsOutput, err := syncRunner.Call(ctx, mutableBody, string(oldDoc._rawBody), metaMap, syncOptions)
1726-
if err != nil {
1720+
}
17271721

1728-
return nil, &base.SyncFnDryRunError{Err: err}
1729-
}
1730-
output = jsOutput.(*channels.ChannelMapperOutput)
1722+
// create new sync runner instance for this dry run
1723+
jsTimeout := time.Duration(base.DefaultJavascriptTimeoutSecs) * time.Second
1724+
syncRunner, err := channels.NewSyncRunnerWithLogging(ctx, syncFn, jsTimeout, errorLogFunc, infoLogFunc)
1725+
if err != nil {
1726+
return nil, fmt.Errorf("failed to create sync runner: %v", err)
1727+
}
1728+
1729+
jsOutput, err := syncRunner.Call(ctx, mutableBody, sgbucket.JSONString(oldDoc._rawBody), metaMap, syncOptions)
1730+
if err != nil {
1731+
return nil, &base.SyncFnDryRunError{Err: err}
17311732
}
17321733

1733-
return output, syncErr
1734+
return jsOutput.(*channels.ChannelMapperOutput), nil
17341735
}
17351736

17361737
// revTreeConflictCheck checks for conflicts in the rev tree history and returns the parent revid, currentRevIndex

rest/diagnostic_doc_api.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@ import (
2020
"github.com/couchbase/sync_gateway/db"
2121
)
2222

23+
type SyncFnDryRunLogging struct {
24+
Errors []string `json:"errors"`
25+
Info []string `json:"info"`
26+
}
27+
2328
type SyncFnDryRun struct {
24-
Channels base.Set `json:"channels"`
25-
Access channels.AccessMap `json:"access"`
26-
Roles channels.AccessMap `json:"roles"`
27-
Exception string `json:"exception"`
28-
Expiry *uint32 `json:"expiry,omitempty"`
29+
Channels base.Set `json:"channels"`
30+
Access channels.AccessMap `json:"access"`
31+
Roles channels.AccessMap `json:"roles"`
32+
Exception string `json:"exception,omitempty"`
33+
Expiry *uint32 `json:"expiry,omitempty"`
34+
Logging SyncFnDryRunLogging `json:"logging"`
2935
}
3036

3137
type ImportFilterDryRun struct {
@@ -87,7 +93,7 @@ func (h *handler) handleSyncFnDryRun() error {
8793
}
8894

8995
if syncDryRunPayload.Doc == nil && docid == "" {
90-
return base.HTTPErrorf(http.StatusBadRequest, "no docid or document provided")
96+
return base.HTTPErrorf(http.StatusBadRequest, "no doc_id or document provided")
9197
}
9298

9399
oldDoc := &db.Document{ID: docid}
@@ -148,7 +154,16 @@ func (h *handler) handleSyncFnDryRun() error {
148154
newRev := db.CreateRevIDWithBytes(generation, matchRev, rawDocBytes)
149155
newDoc.RevID = newRev
150156

151-
output, err := h.collection.SyncFnDryrun(h.ctx(), newDoc, oldDoc, syncDryRunPayload.Function)
157+
logErrors := make([]string, 0)
158+
logInfo := make([]string, 0)
159+
errorLogFn := func(s string) {
160+
logErrors = append(logErrors, s)
161+
}
162+
infoLogFn := func(s string) {
163+
logInfo = append(logInfo, s)
164+
}
165+
166+
output, err := h.collection.SyncFnDryrun(h.ctx(), newDoc, oldDoc, syncDryRunPayload.Function, errorLogFn, infoLogFn)
152167
if err != nil {
153168
var syncFnDryRunErr *base.SyncFnDryRunError
154169
if !errors.As(err, &syncFnDryRunErr) {
@@ -158,6 +173,7 @@ func (h *handler) handleSyncFnDryRun() error {
158173
errMsg := syncFnDryRunErr.Error()
159174
resp := SyncFnDryRun{
160175
Exception: errMsg,
176+
Logging: SyncFnDryRunLogging{Errors: logErrors, Info: logInfo},
161177
}
162178
h.writeJSON(resp)
163179
return nil
@@ -173,6 +189,7 @@ func (h *handler) handleSyncFnDryRun() error {
173189
output.Roles,
174190
errorMsg,
175191
output.Expiry,
192+
SyncFnDryRunLogging{Errors: logErrors, Info: logInfo},
176193
}
177194
h.writeJSON(resp)
178195
return nil

0 commit comments

Comments
 (0)