1.4.5.2
This commit is contained in:
115
EdgeNode/internal/js/isolate.go
Normal file
115
EdgeNode/internal/js/isolate.go
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build script
|
||||
// +build script
|
||||
|
||||
package js
|
||||
|
||||
import (
|
||||
"rogchap.com/v8go"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
const maxContextsPerIsolate = 8 // TODO 根据系统内存动态调整
|
||||
|
||||
type Isolate struct {
|
||||
rawIsolate *v8go.Isolate
|
||||
|
||||
contextPool *ContextPool
|
||||
countUses uint32
|
||||
|
||||
isDisposed bool
|
||||
}
|
||||
|
||||
func NewIsolate() (*Isolate, error) {
|
||||
return NewIsolateWithContexts(maxContextsPerIsolate)
|
||||
}
|
||||
|
||||
func NewIsolateWithContexts(contextSize int) (*Isolate, error) {
|
||||
var isolate = &Isolate{
|
||||
rawIsolate: v8go.NewIsolate(),
|
||||
contextPool: NewContextPool(contextSize),
|
||||
}
|
||||
err := isolate.init()
|
||||
if err != nil {
|
||||
isolate.Dispose()
|
||||
return nil, err
|
||||
}
|
||||
return isolate, nil
|
||||
}
|
||||
|
||||
func (this *Isolate) init() error {
|
||||
// 初始化context
|
||||
for i := 0; i < this.contextPool.MaxSize(); i++ {
|
||||
ctx, err := this.createContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
this.contextPool.Put(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Isolate) OverUses() bool {
|
||||
return atomic.LoadUint32(&this.countUses) > 4096
|
||||
}
|
||||
|
||||
func (this *Isolate) GetContext() (*Context, error) {
|
||||
atomic.AddUint32(&this.countUses, 1)
|
||||
|
||||
ctx := this.contextPool.Get()
|
||||
if ctx != nil {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
ctx, err := this.createContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func (this *Isolate) PutContext(ctx *Context) {
|
||||
ctx.Done()
|
||||
this.contextPool.Put(ctx)
|
||||
}
|
||||
|
||||
func (this *Isolate) Compile(source string, origin string) (*Script, error) {
|
||||
script, err := this.rawIsolate.CompileUnboundScript(source, origin, v8go.CompileOptions{
|
||||
Mode: v8go.CompileModeDefault,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewScript(script), nil
|
||||
}
|
||||
|
||||
func (this *Isolate) ContextPool() *ContextPool {
|
||||
return this.contextPool
|
||||
}
|
||||
|
||||
func (this *Isolate) RawIsolate() *v8go.Isolate {
|
||||
return this.rawIsolate
|
||||
}
|
||||
|
||||
func (this *Isolate) ThrowException(value *v8go.Value) *v8go.Value {
|
||||
return this.rawIsolate.ThrowException(value)
|
||||
}
|
||||
|
||||
func (this *Isolate) IsUsing() bool {
|
||||
return this.contextPool.IsUsing()
|
||||
}
|
||||
|
||||
func (this *Isolate) Dispose() {
|
||||
if this.isDisposed {
|
||||
return
|
||||
}
|
||||
this.isDisposed = true
|
||||
|
||||
this.contextPool.Close()
|
||||
this.rawIsolate.Dispose()
|
||||
}
|
||||
|
||||
func (this *Isolate) createContext() (*Context, error) {
|
||||
return NewContext(v8go.NewContext(this.rawIsolate), this)
|
||||
}
|
||||
Reference in New Issue
Block a user