Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
3aaf810e
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
3aaf810e
编写于
9月 29, 2021
作者:
C
Connor Peet
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
experiments: allow multiple activation events
上级
1f32001c
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
83 addition
and
43 deletion
+83
-43
src/vs/workbench/contrib/experiments/common/experimentService.ts
...workbench/contrib/experiments/common/experimentService.ts
+36
-23
src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts
...periments/test/electron-browser/experimentService.test.ts
+47
-20
未找到文件。
src/vs/workbench/contrib/experiments/common/experimentService.ts
浏览文件 @
3aaf810e
...
...
@@ -3,26 +3,27 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
distinct
}
from
'
vs/base/common/arrays
'
;
import
{
RunOnceWorker
}
from
'
vs/base/common/async
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
IStorageService
,
StorageScope
,
StorageTarget
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ITelemetryService
,
lastSessionDateStorageKey
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
ILifecycleService
,
LifecyclePhase
}
from
'
vs/workbench/services/lifecycle/common/lifecycle
'
;
import
{
match
}
from
'
vs/base/common/glob
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
equals
}
from
'
vs/base/common/objects
'
;
import
{
language
,
OperatingSystem
,
OS
}
from
'
vs/base/common/platform
'
;
import
{
isDefined
}
from
'
vs/base/common/types
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IExtensionManagementService
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
language
,
OperatingSystem
,
OS
}
from
'
vs/base/common/platform
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
match
}
from
'
vs/base/common/glob
'
;
import
{
IRequestService
,
asJson
}
from
'
vs/platform/request/common/request
'
;
import
{
ITextFileService
,
ITextFileEditorModel
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
{
distinct
}
from
'
vs/base/common/arrays
'
;
import
{
ExtensionType
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IProductService
}
from
'
vs/platform/product/common/productService
'
;
import
{
asJson
,
IRequestService
}
from
'
vs/platform/request/common/request
'
;
import
{
IStorageService
,
StorageScope
,
StorageTarget
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ITelemetryService
,
lastSessionDateStorageKey
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
IWorkspaceTagsService
}
from
'
vs/workbench/contrib/tags/common/workspaceTags
'
;
import
{
RunOnceWorker
}
from
'
vs/base/common/async
'
;
import
{
IExtensionService
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
equals
}
from
'
vs/base/common/objects
'
;
import
{
ILifecycleService
,
LifecyclePhase
}
from
'
vs/workbench/services/lifecycle/common/lifecycle
'
;
import
{
ITextFileEditorModel
,
ITextFileService
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
export
const
enum
ExperimentState
{
Evaluating
,
...
...
@@ -93,7 +94,7 @@ interface IExperimentStorageState {
* be incremented when adding a condition, otherwise experiments might activate
* on older versions of VS Code where not intended.
*/
export
const
currentSchemaVersion
=
4
;
export
const
currentSchemaVersion
=
5
;
interface
IRawExperiment
{
id
:
string
;
...
...
@@ -107,7 +108,7 @@ interface IRawExperiment {
userSetting
?:
{
[
key
:
string
]:
unknown
;
};
// Start the experiment if the number of activation events have happened over the last week:
activationEvent
?:
{
event
:
string
;
event
:
string
|
string
[]
;
uniqueDays
?:
number
;
minEvents
:
number
;
};
...
...
@@ -285,7 +286,8 @@ export class ExperimentService extends Disposable implements IExperimentService
this
.
storageService
.
remove
(
'
allExperiments
'
,
StorageScope
.
GLOBAL
);
}
const
activationEvents
=
new
Set
(
rawExperiments
.
map
(
exp
=>
exp
.
condition
?.
activationEvent
?.
event
).
filter
(
evt
=>
!!
evt
));
const
activationEvents
=
new
Set
(
rawExperiments
.
map
(
exp
=>
exp
.
condition
?.
activationEvent
?.
event
)
.
filter
(
isDefined
).
flatMap
(
evt
=>
typeof
evt
===
'
string
'
?
[
evt
]
:
[]));
if
(
activationEvents
.
size
)
{
this
.
_register
(
this
.
extensionService
.
onWillActivateByEvent
(
evt
=>
{
if
(
activationEvents
.
has
(
evt
.
event
))
{
...
...
@@ -402,7 +404,14 @@ export class ExperimentService extends Disposable implements IExperimentService
this
.
storageService
.
store
(
key
,
JSON
.
stringify
(
record
),
StorageScope
.
GLOBAL
,
StorageTarget
.
MACHINE
);
this
.
_experiments
.
filter
(
e
=>
e
.
state
===
ExperimentState
.
Evaluating
&&
e
.
raw
?.
condition
?.
activationEvent
?.
event
===
event
)
.
filter
(
e
=>
{
const
lookingFor
=
e
.
raw
?.
condition
?.
activationEvent
?.
event
;
if
(
e
.
state
!==
ExperimentState
.
Evaluating
||
!
lookingFor
)
{
return
false
;
}
return
typeof
lookingFor
===
'
string
'
?
lookingFor
===
event
:
lookingFor
?.
includes
(
event
);
})
.
forEach
(
e
=>
this
.
evaluateExperiment
(
e
.
raw
!
));
}
...
...
@@ -412,16 +421,20 @@ export class ExperimentService extends Disposable implements IExperimentService
return
true
;
}
const
{
count
}
=
getCurrentActivationRecord
(
safeParse
(
this
.
storageService
.
get
(
experimentEventStorageKey
(
setting
.
event
),
StorageScope
.
GLOBAL
),
undefined
));
let
total
=
0
;
let
uniqueDays
=
0
;
const
events
=
typeof
setting
.
event
===
'
string
'
?
[
setting
.
event
]
:
setting
.
event
;
for
(
const
event
of
events
)
{
const
{
count
}
=
getCurrentActivationRecord
(
safeParse
(
this
.
storageService
.
get
(
experimentEventStorageKey
(
event
),
StorageScope
.
GLOBAL
),
undefined
));
for
(
const
entry
of
count
)
{
if
(
entry
>
0
)
{
uniqueDays
++
;
total
+=
entry
;
}
}
}
return
total
>=
setting
.
minEvents
&&
(
!
setting
.
uniqueDays
||
uniqueDays
>=
setting
.
uniqueDays
);
}
...
...
src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts
浏览文件 @
3aaf810e
...
...
@@ -5,34 +5,32 @@
import
*
as
assert
from
'
assert
'
;
import
*
as
sinon
from
'
sinon
'
;
import
{
ExperimentActionType
,
ExperimentState
,
IExperiment
,
ExperimentService
,
getCurrentActivationRecord
,
currentSchemaVersion
}
from
'
vs/workbench/contrib/experiments/common/experimentService
'
;
import
{
TestInstantiationService
}
from
'
vs/platform/instantiation/test/common/instantiationServiceMock
'
;
import
{
TestLifecycleService
}
from
'
vs/workbench/test/browser/workbenchTestServices
'
;
import
{
IExtensionManagementService
,
DidUninstallExtensionEvent
,
InstallExtensionEvent
,
IExtensionIdentifier
,
ILocalExtension
,
InstallExtensionResult
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
IWorkbenchExtensionEnablementService
}
from
'
vs/workbench/services/extensionManagement/common/extensionManagement
'
;
import
{
ExtensionManagementService
}
from
'
vs/platform/extensionManagement/node/extensionManagementService
'
;
import
{
timeout
}
from
'
vs/base/common/async
'
;
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
TestExtensionEnablementService
}
from
'
vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test
'
;
import
{
NativeURLService
}
from
'
vs/platform/url/common/urlService
'
;
import
{
IURLService
}
from
'
vs/platform/url/common/url
'
;
import
{
ITelemetryService
,
lastSessionDateStorageKey
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
NullTelemetryService
}
from
'
vs/platform/telemetry/common/telemetryUtils
'
;
import
{
OS
}
from
'
vs/base/common/platform
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
TestConfigurationService
}
from
'
vs/platform/configuration/test/common/testConfigurationService
'
;
import
{
ILifecycleService
}
from
'
vs/workbench/services/lifecycle/common/lifecycle
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
DidUninstallExtensionEvent
,
IExtensionIdentifier
,
IExtensionManagementService
,
ILocalExtension
,
InstallExtensionEvent
,
InstallExtensionResult
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
getGalleryExtensionId
}
from
'
vs/platform/extensionManagement/common/extensionManagementUtil
'
;
import
{
ExtensionManagementService
}
from
'
vs/platform/extensionManagement/node/extensionManagementService
'
;
import
{
ExtensionType
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
TestInstantiationService
}
from
'
vs/platform/instantiation/test/common/instantiationServiceMock
'
;
import
{
IProductService
}
from
'
vs/platform/product/common/productService
'
;
import
{
IWillActivateEvent
,
IExtensionService
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
timeout
}
from
'
vs/base/common/async
'
;
import
{
TestExtensionService
}
from
'
vs/workbench/test/common/workbenchTestServices
'
;
import
{
OS
}
from
'
vs/base/common/platform
'
;
import
{
IStorageService
,
StorageScope
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ITelemetryService
,
lastSessionDateStorageKey
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
NullTelemetryService
}
from
'
vs/platform/telemetry/common/telemetryUtils
'
;
import
{
IURLService
}
from
'
vs/platform/url/common/url
'
;
import
{
NativeURLService
}
from
'
vs/platform/url/common/urlService
'
;
import
{
IWorkspaceTrustManagementService
}
from
'
vs/platform/workspace/common/workspaceTrust
'
;
import
{
currentSchemaVersion
,
ExperimentActionType
,
ExperimentService
,
ExperimentState
,
getCurrentActivationRecord
,
IExperiment
}
from
'
vs/workbench/contrib/experiments/common/experimentService
'
;
import
{
IWorkbenchExtensionEnablementService
}
from
'
vs/workbench/services/extensionManagement/common/extensionManagement
'
;
import
{
TestExtensionEnablementService
}
from
'
vs/workbench/services/extensionManagement/test/browser/extensionEnablementService.test
'
;
import
{
IExtensionService
,
IWillActivateEvent
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
ILifecycleService
}
from
'
vs/workbench/services/lifecycle/common/lifecycle
'
;
import
{
TestWorkspaceTrustManagementService
}
from
'
vs/workbench/services/workspaces/test/common/testWorkspaceTrustService
'
;
import
{
TestLifecycleService
}
from
'
vs/workbench/test/browser/workbenchTestServices
'
;
import
{
TestExtensionService
}
from
'
vs/workbench/test/common/workbenchTestServices
'
;
interface
ExperimentSettings
{
enabled
?:
boolean
;
...
...
@@ -407,6 +405,35 @@ suite('Experiment Service', () => {
});
});
test
(
'
Activation event allows multiple
'
,
()
=>
{
experimentData
=
{
experiments
:
[
{
id
:
'
experiment1
'
,
enabled
:
true
,
condition
:
{
activationEvent
:
{
event
:
[
'
other:event
'
,
'
my:event
'
],
minEvents
:
5
,
}
}
}
]
};
instantiationService
.
stub
(
IStorageService
,
'
get
'
,
(
a
:
string
,
b
:
StorageScope
,
c
?:
string
)
=>
{
return
a
===
'
experimentEventRecord-my-event
'
?
JSON
.
stringify
({
count
:
[
10
],
mostRecentBucket
:
Date
.
now
()
})
:
undefined
;
});
testObject
=
instantiationService
.
createInstance
(
TestExperimentService
);
return
testObject
.
getExperimentById
(
'
experiment1
'
).
then
(
result
=>
{
assert
.
strictEqual
(
result
.
enabled
,
true
);
assert
.
strictEqual
(
result
.
state
,
ExperimentState
.
Run
);
});
});
test
(
'
Activation event does not work with old data
'
,
()
=>
{
experimentData
=
{
experiments
:
[
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录