Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit f074351

Browse files
committed
Refactor frame execution contexts
1 parent 135776b commit f074351

File tree

3 files changed

+33
-36
lines changed

3 files changed

+33
-36
lines changed

common/execution_context.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const (
4545
utilityWorld executionWorld = "utility"
4646
)
4747

48+
func (ew executionWorld) valid() bool {
49+
return ew == mainWorld || ew == utilityWorld
50+
}
51+
4852
type evaluateOptions struct {
4953
forceCallable, returnByValue bool
5054
}

common/frame.go

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ type Frame struct {
7070

7171
documentHandle *ElementHandle
7272

73-
executionContextMu sync.RWMutex
74-
mainExecutionContext frameExecutionContext
75-
utilityExecutionContext frameExecutionContext
73+
executionContextMu sync.RWMutex
74+
executionContexts map[executionWorld]frameExecutionContext
7675

7776
loadingStartedTime time.Time
7877

@@ -112,6 +111,7 @@ func NewFrame(ctx context.Context, m *FrameManager, parentFrame *Frame, frameID
112111
lifecycleEvents: make(map[LifecycleEvent]bool),
113112
subtreeLifecycleEvents: make(map[LifecycleEvent]bool),
114113
inflightRequests: make(map[network.RequestID]bool),
114+
executionContexts: make(map[executionWorld]frameExecutionContext),
115115
currentDocument: &DocumentInfo{},
116116
networkIdleCh: make(chan struct{}),
117117
log: log,
@@ -341,7 +341,7 @@ func (f *Frame) hasContext(world executionWorld) bool {
341341
f.executionContextMu.RLock()
342342
defer f.executionContextMu.RUnlock()
343343

344-
return f.getExecCtx(world) != nil
344+
return f.executionContexts[world] != nil
345345
}
346346

347347
func (f *Frame) hasLifecycleEventFired(event LifecycleEvent) bool {
@@ -375,11 +375,13 @@ func (f *Frame) nullContext(execCtxID runtime.ExecutionContextID) {
375375
f.executionContextMu.Lock()
376376
defer f.executionContextMu.Unlock()
377377

378-
if f.mainExecutionContext != nil && f.mainExecutionContext.ID() == execCtxID {
379-
f.mainExecutionContext = nil
378+
if ec := f.executionContexts[mainWorld]; ec != nil && ec.ID() == execCtxID {
379+
f.executionContexts[mainWorld] = nil
380380
f.documentHandle = nil
381-
} else if f.utilityExecutionContext != nil && f.utilityExecutionContext.ID() == execCtxID {
382-
f.utilityExecutionContext = nil
381+
return
382+
}
383+
if ec := f.executionContexts[utilityWorld]; ec != nil && ec.ID() == execCtxID {
384+
f.executionContexts[utilityWorld] = nil
383385
}
384386
}
385387

@@ -450,19 +452,20 @@ func (f *Frame) setContext(world executionWorld, execCtx frameExecutionContext)
450452
f.log.Debugf("Frame:setContext", "fid:%s furl:%q ectxid:%d world:%s",
451453
f.ID(), f.URL(), execCtx.ID(), world)
452454

453-
switch world {
454-
case mainWorld:
455-
if f.mainExecutionContext == nil {
456-
f.mainExecutionContext = execCtx
457-
}
458-
case utilityWorld:
459-
if f.utilityExecutionContext == nil {
460-
f.utilityExecutionContext = execCtx
461-
}
462-
default:
455+
if !world.valid() {
463456
err := fmt.Errorf("unknown world: %q, it should be either main or utility", world)
464457
panic(err)
465458
}
459+
460+
if f.executionContexts[world] != nil {
461+
f.log.Debugf("Frame:setContext", "fid:%s furl:%q ectxid:%d world:%s, world exists",
462+
f.ID(), f.URL(), execCtx.ID(), world)
463+
return
464+
}
465+
466+
f.executionContexts[world] = execCtx
467+
f.log.Debugf("Frame:setContext", "fid:%s furl:%q ectxid:%d world:%s, world set",
468+
f.ID(), f.URL(), execCtx.ID(), world)
466469
}
467470

468471
func (f *Frame) setID(id cdp.FrameID) {
@@ -501,7 +504,7 @@ func (f *Frame) waitForFunction(apiCtx context.Context, world executionWorld, pr
501504
f.executionContextMu.RLock()
502505
defer f.executionContextMu.RUnlock()
503506

504-
execCtx := f.getExecCtx(world)
507+
execCtx := f.executionContexts[world]
505508
injected, err := execCtx.getInjectedScript(apiCtx)
506509
if err != nil {
507510
return nil, err
@@ -556,10 +559,9 @@ func (f *Frame) waitForSelector(selector string, opts *FrameWaitForSelectorOptio
556559
f.executionContextMu.RLock()
557560
defer f.executionContextMu.RUnlock()
558561

559-
if handle.execCtx != f.mainExecutionContext {
562+
if ec := f.executionContexts[mainWorld]; handle.execCtx != ec {
560563
defer handle.Dispose()
561-
handle, err = f.mainExecutionContext.adoptElementHandle(handle)
562-
if err != nil {
564+
if handle, err = ec.adoptElementHandle(handle); err != nil {
563565
return nil, err
564566
}
565567
}
@@ -730,7 +732,8 @@ func (f *Frame) EvaluateHandle(pageFunc goja.Value, args ...goja.Value) (handle
730732
var err error
731733
f.executionContextMu.RLock()
732734
{
733-
handle, err = f.mainExecutionContext.EvaluateHandle(f.ctx, pageFunc, args...)
735+
ec := f.executionContexts[mainWorld]
736+
handle, err = ec.EvaluateHandle(f.ctx, pageFunc, args...)
734737
}
735738
f.executionContextMu.RUnlock()
736739
if err != nil {
@@ -1438,28 +1441,18 @@ func (f *Frame) adoptBackendNodeID(world executionWorld, id cdp.BackendNodeID) (
14381441
f.executionContextMu.RLock()
14391442
defer f.executionContextMu.RUnlock()
14401443

1441-
ec := f.getExecCtx(world)
1444+
ec := f.executionContexts[world]
14421445
return ec.adoptBackendNodeID(id)
14431446
}
14441447

14451448
func (f *Frame) evaluate(world executionWorld, apiCtx context.Context, opts evaluateOptions, pageFunc goja.Value, args ...goja.Value) (res interface{}, err error) {
14461449
f.executionContextMu.RLock()
14471450
defer f.executionContextMu.RUnlock()
14481451

1449-
ec := f.getExecCtx(world)
1452+
ec := f.executionContexts[world]
14501453
return ec.evaluate(apiCtx, opts, pageFunc, args...)
14511454
}
14521455

1453-
// getExecCtx returns an execution context using a given world name.
1454-
// Unsafe to use concurrently.
1455-
func (f *Frame) getExecCtx(world executionWorld) frameExecutionContext {
1456-
ec := f.mainExecutionContext
1457-
if world == utilityWorld {
1458-
ec = f.utilityExecutionContext
1459-
}
1460-
return ec
1461-
}
1462-
14631456
// frameExecutionContext represents a JS execution context that belongs to Frame.
14641457
type frameExecutionContext interface {
14651458
// adoptBackendNodeID adopts specified backend node into this execution

common/frame_session.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ func (fs *FrameSession) onAttachedToTarget(event *target.EventAttachedToTarget)
801801
}
802802
// Erroneous cases
803803
defer fs.logger.Debugf("FrameSession:onAttachedToTarget:NewFrameSession",
804-
"sid:%v tid:%v esid:%v etid:%v ebctxid:%v type:%q err:%t",
804+
"sid:%v tid:%v esid:%v etid:%v ebctxid:%v type:%q err:%v",
805805
fs.session.id, fs.targetID, event.SessionID,
806806
event.TargetInfo.TargetID, event.TargetInfo.BrowserContextID,
807807
event.TargetInfo.Type, err)

0 commit comments

Comments
 (0)