Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
8e89e343
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
8e89e343
编写于
5月 22, 2019
作者:
A
Alex Dima
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add extension host client
上级
8a7c6a0c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
417 addition
and
34 deletion
+417
-34
src/vs/workbench/services/extensions/electron-browser/extensionService.ts
.../services/extensions/electron-browser/extensionService.ts
+170
-34
src/vs/workbench/services/extensions/electron-browser/remoteExtensionHostClient.ts
.../extensions/electron-browser/remoteExtensionHostClient.ts
+247
-0
未找到文件。
src/vs/workbench/services/extensions/electron-browser/extensionService.ts
浏览文件 @
8e89e343
...
...
@@ -16,6 +16,12 @@ import { URI } from 'vs/base/common/uri';
import
{
IWorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/common/environmentService
'
;
import
{
EnablementState
,
IExtensionEnablementService
,
IExtensionIdentifier
,
IExtensionManagementService
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
BetterMergeId
,
areSameExtensions
}
from
'
vs/platform/extensionManagement/common/extensionManagementUtil
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
IInitDataProvider
,
RemoteExtensionHostClient
}
from
'
vs/workbench/services/extensions/electron-browser/remoteExtensionHostClient
'
;
import
{
IRemoteAgentService
}
from
'
vs/workbench/services/remote/common/remoteAgentService
'
;
import
{
IRemoteAuthorityResolverService
,
ResolvedAuthority
,
RemoteAuthorityResolverError
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
{
isUIExtension
}
from
'
vs/workbench/services/extensions/node/extensionsUtil
'
;
import
{
IRemoteAgentEnvironment
}
from
'
vs/platform/remote/common/remoteAgentEnvironment
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
ILifecycleService
,
LifecyclePhase
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
pkg
from
'
vs/platform/product/node/package
'
;
...
...
@@ -35,6 +41,7 @@ import { Schemas } from 'vs/base/common/network';
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
parseExtensionDevOptions
}
from
'
vs/workbench/services/extensions/common/extensionDevOptions
'
;
import
{
PersistenConnectionEventType
}
from
'
vs/platform/remote/common/remoteAgentConnection
'
;
const
hasOwnProperty
=
Object
.
hasOwnProperty
;
const
NO_OP_VOID_PROMISE
=
Promise
.
resolve
<
void
>
(
undefined
);
...
...
@@ -64,6 +71,8 @@ export class ExtensionService extends Disposable implements IExtensionService {
public
_serviceBrand
:
any
;
private
_remoteExtensionsEnvironmentData
:
Map
<
string
,
IRemoteAgentEnvironment
>
;
private
readonly
_extensionHostLogsLocation
:
URI
;
private
readonly
_registry
:
ExtensionDescriptionRegistry
;
private
readonly
_installedExtensionsReady
:
Barrier
;
...
...
@@ -102,6 +111,9 @@ export class ExtensionService extends Disposable implements IExtensionService {
@
IExtensionEnablementService
private
readonly
_extensionEnablementService
:
IExtensionEnablementService
,
@
IExtensionManagementService
private
readonly
_extensionManagementService
:
IExtensionManagementService
,
@
IWindowService
private
readonly
_windowService
:
IWindowService
,
@
IRemoteAgentService
private
readonly
_remoteAgentService
:
IRemoteAgentService
,
@
IRemoteAuthorityResolverService
private
readonly
_remoteAuthorityResolverService
:
IRemoteAuthorityResolverService
,
@
IConfigurationService
private
readonly
_configurationService
:
IConfigurationService
,
@
ILifecycleService
private
readonly
_lifecycleService
:
ILifecycleService
,
@
IFileService
fileService
:
IFileService
)
{
...
...
@@ -112,7 +124,9 @@ export class ExtensionService extends Disposable implements IExtensionService {
e
.
join
(
this
.
activateByEvent
(
`onFileSystem:
${
e
.
scheme
}
`
));
}));
this
.
_extensionHostLogsLocation
=
URI
.
file
(
path
.
join
(
this
.
_environmentService
.
logsPath
,
`exthost
${
this
.
_windowService
.
windowId
}
`
));
this
.
_remoteExtensionsEnvironmentData
=
new
Map
<
string
,
IRemoteAgentEnvironment
>
();
this
.
_extensionHostLogsLocation
=
URI
.
file
(
path
.
join
(
this
.
_environmentService
.
logsPath
,
`exthost
${
_windowService
.
windowId
}
`
));
this
.
_registry
=
new
ExtensionDescriptionRegistry
([]);
this
.
_installedExtensionsReady
=
new
Barrier
();
this
.
_isDev
=
!
this
.
_environmentService
.
isBuilt
||
this
.
_environmentService
.
isExtensionDevelopment
;
...
...
@@ -425,6 +439,17 @@ export class ExtensionService extends Disposable implements IExtensionService {
}
}
private
_createProvider
(
remoteAuthority
:
string
):
IInitDataProvider
{
return
{
remoteAuthority
:
remoteAuthority
,
getInitData
:
()
=>
{
return
this
.
_installedExtensionsReady
.
wait
().
then
(()
=>
{
return
this
.
_remoteExtensionsEnvironmentData
.
get
(
remoteAuthority
)
!
;
});
}
};
}
private
_startExtensionHostProcess
(
isInitialStart
:
boolean
,
initialActivationEvents
:
string
[]):
void
{
this
.
_stopExtensionHostProcess
();
...
...
@@ -436,52 +461,63 @@ export class ExtensionService extends Disposable implements IExtensionService {
}
else
{
// restart case
autoStart
=
true
;
extensions
=
this
.
getExtensions
();
extensions
=
this
.
getExtensions
()
.
then
((
extensions
)
=>
extensions
.
filter
(
ext
=>
ext
.
extensionLocation
.
scheme
===
Schemas
.
file
))
;
}
const
extHostProcessWorker
=
this
.
_instantiationService
.
createInstance
(
ExtensionHostProcessWorker
,
autoStart
,
extensions
,
this
.
_extensionHostLogsLocation
);
const
extHostProcessManager
=
this
.
_instantiationService
.
createInstance
(
ExtensionHostProcessManager
,
extHostProcessWorker
,
null
,
initialActivationEvents
);
extHostProcessManager
.
onDidCrash
(([
code
,
signal
])
=>
this
.
_onExtensionHostCrashed
(
code
,
signal
));
extHostProcessManager
.
onDidCrash
(([
code
,
signal
])
=>
this
.
_onExtensionHostCrashed
(
code
,
signal
,
true
));
extHostProcessManager
.
onDidChangeResponsiveState
((
responsiveState
)
=>
{
this
.
_onDidChangeResponsiveChange
.
fire
({
isResponsive
:
responsiveState
===
ResponsiveState
.
Responsive
});
});
this
.
_extensionHostProcessManagers
.
push
(
extHostProcessManager
);
const
remoteAgentConnection
=
this
.
_remoteAgentService
.
getConnection
();
if
(
remoteAgentConnection
)
{
const
remoteExtHostProcessWorker
=
this
.
_instantiationService
.
createInstance
(
RemoteExtensionHostClient
,
this
.
getExtensions
(),
this
.
_createProvider
(
remoteAgentConnection
.
remoteAuthority
));
const
remoteExtHostProcessManager
=
this
.
_instantiationService
.
createInstance
(
ExtensionHostProcessManager
,
remoteExtHostProcessWorker
,
remoteAgentConnection
.
remoteAuthority
,
initialActivationEvents
);
remoteExtHostProcessManager
.
onDidCrash
(([
code
,
signal
])
=>
this
.
_onExtensionHostCrashed
(
code
,
signal
,
false
));
remoteExtHostProcessManager
.
onDidChangeResponsiveState
((
responsiveState
)
=>
{
this
.
_onDidChangeResponsiveChange
.
fire
({
isResponsive
:
responsiveState
===
ResponsiveState
.
Responsive
});
});
this
.
_extensionHostProcessManagers
.
push
(
remoteExtHostProcessManager
);
}
}
private
_onExtensionHostCrashed
(
code
:
number
,
signal
:
string
|
null
):
void
{
private
_onExtensionHostCrashed
(
code
:
number
,
signal
:
string
|
null
,
showNotification
:
boolean
):
void
{
console
.
error
(
'
Extension host terminated unexpectedly. Code:
'
,
code
,
'
Signal:
'
,
signal
);
this
.
_stopExtensionHostProcess
();
if
(
code
===
55
)
{
this
.
_notificationService
.
prompt
(
Severity
.
Error
,
nls
.
localize
(
'
extensionService.versionMismatchCrash
'
,
"
Extension host cannot start: version mismatch.
"
),
if
(
showNotification
)
{
if
(
code
===
55
)
{
this
.
_notificationService
.
prompt
(
Severity
.
Error
,
nls
.
localize
(
'
extensionService.versionMismatchCrash
'
,
"
Extension host cannot start: version mismatch.
"
),
[{
label
:
nls
.
localize
(
'
relaunch
'
,
"
Relaunch VS Code
"
),
run
:
()
=>
{
this
.
_instantiationService
.
invokeFunction
((
accessor
)
=>
{
const
windowsService
=
accessor
.
get
(
IWindowsService
);
windowsService
.
relaunch
({});
});
}
}]
);
return
;
}
let
message
=
nls
.
localize
(
'
extensionService.crash
'
,
"
Extension host terminated unexpectedly.
"
);
if
(
code
===
87
)
{
message
=
nls
.
localize
(
'
extensionService.unresponsiveCrash
'
,
"
Extension host terminated because it was not responsive.
"
);
}
this
.
_notificationService
.
prompt
(
Severity
.
Error
,
message
,
[{
label
:
nls
.
localize
(
'
relaunch
'
,
"
Relaunch VS Code
"
),
run
:
()
=>
{
this
.
_instantiationService
.
invokeFunction
((
accessor
)
=>
{
const
windowsService
=
accessor
.
get
(
IWindowsService
);
windowsService
.
relaunch
({});
});
}
label
:
nls
.
localize
(
'
devTools
'
,
"
Open Developer Tools
"
),
run
:
()
=>
this
.
_windowService
.
openDevTools
()
},
{
label
:
nls
.
localize
(
'
restart
'
,
"
Restart Extension Host
"
),
run
:
()
=>
this
.
_startExtensionHostProcess
(
false
,
Object
.
keys
(
this
.
_allRequestedActivateEvents
))
}]
);
return
;
}
let
message
=
nls
.
localize
(
'
extensionService.crash
'
,
"
Extension host terminated unexpectedly.
"
);
if
(
code
===
87
)
{
message
=
nls
.
localize
(
'
extensionService.unresponsiveCrash
'
,
"
Extension host terminated because it was not responsive.
"
);
}
this
.
_notificationService
.
prompt
(
Severity
.
Error
,
message
,
[{
label
:
nls
.
localize
(
'
devTools
'
,
"
Open Developer Tools
"
),
run
:
()
=>
this
.
_windowService
.
openDevTools
()
},
{
label
:
nls
.
localize
(
'
restart
'
,
"
Restart Extension Host
"
),
run
:
()
=>
this
.
_startExtensionHostProcess
(
false
,
Object
.
keys
(
this
.
_allRequestedActivateEvents
))
}]
);
}
// ---- begin IExtensionService
...
...
@@ -590,12 +626,112 @@ export class ExtensionService extends Disposable implements IExtensionService {
});
}
private
async
_resolveAuthorityAgain
():
Promise
<
void
>
{
const
remoteAuthority
=
this
.
_environmentService
.
configuration
.
remoteAuthority
;
if
(
!
remoteAuthority
)
{
return
;
}
const
extensionHost
=
this
.
_extensionHostProcessManagers
[
0
];
this
.
_remoteAuthorityResolverService
.
clearResolvedAuthority
(
remoteAuthority
);
try
{
const
resolvedAuthority
=
await
extensionHost
.
resolveAuthority
(
remoteAuthority
);
this
.
_remoteAuthorityResolverService
.
setResolvedAuthority
(
resolvedAuthority
);
}
catch
(
err
)
{
this
.
_remoteAuthorityResolverService
.
setResolvedAuthorityError
(
remoteAuthority
,
err
);
}
}
private
async
_scanAndHandleExtensions
():
Promise
<
void
>
{
this
.
_extensionScanner
.
startScanningExtensions
(
this
.
createLogger
());
const
remoteAuthority
=
this
.
_environmentService
.
configuration
.
remoteAuthority
;
const
extensionHost
=
this
.
_extensionHostProcessManagers
[
0
];
const
extensions
=
await
this
.
_extensionScanner
.
scannedExtensions
;
const
enabledExtensions
=
await
this
.
_getRuntimeExtensions
(
extensions
);
let
localExtensions
=
await
this
.
_extensionScanner
.
scannedExtensions
;
if
(
remoteAuthority
)
{
let
resolvedAuthority
:
ResolvedAuthority
;
try
{
resolvedAuthority
=
await
extensionHost
.
resolveAuthority
(
remoteAuthority
);
}
catch
(
err
)
{
console
.
error
(
err
);
const
plusIndex
=
remoteAuthority
.
indexOf
(
'
+
'
);
const
authorityFriendlyName
=
plusIndex
>
0
?
remoteAuthority
.
substr
(
0
,
plusIndex
)
:
remoteAuthority
;
if
(
!
RemoteAuthorityResolverError
.
isHandledNotAvailable
(
err
))
{
this
.
_notificationService
.
notify
({
severity
:
Severity
.
Error
,
message
:
nls
.
localize
(
'
resolveAuthorityFailure
'
,
"
Resolving the authority `{0}` failed
"
,
authorityFriendlyName
)
});
}
else
{
console
.
log
(
`Not showing a notification for the error`
);
}
this
.
_remoteAuthorityResolverService
.
setResolvedAuthorityError
(
remoteAuthority
,
err
);
// Proceed with the local extension host
await
this
.
_startLocalExtensionHost
(
extensionHost
,
localExtensions
);
return
;
}
// set the resolved authority
this
.
_remoteAuthorityResolverService
.
setResolvedAuthority
(
resolvedAuthority
);
// monitor for breakage
const
connection
=
this
.
_remoteAgentService
.
getConnection
();
if
(
connection
)
{
connection
.
onDidStateChange
(
async
(
e
)
=>
{
const
remoteAuthority
=
this
.
_environmentService
.
configuration
.
remoteAuthority
;
if
(
!
remoteAuthority
)
{
return
;
}
if
(
e
.
type
===
PersistenConnectionEventType
.
ConnectionLost
)
{
this
.
_remoteAuthorityResolverService
.
clearResolvedAuthority
(
remoteAuthority
);
}
});
connection
.
onReconnecting
(()
=>
this
.
_resolveAuthorityAgain
());
}
// fetch the remote environment
const
remoteEnv
=
(
await
this
.
_remoteAgentService
.
getEnvironment
())
!
;
// revive URIs
remoteEnv
.
extensions
.
forEach
((
extension
)
=>
{
(
<
any
>
extension
).
extensionLocation
=
URI
.
revive
(
extension
.
extensionLocation
);
});
// remove UI extensions from the remote extensions
remoteEnv
.
extensions
=
remoteEnv
.
extensions
.
filter
(
extension
=>
!
isUIExtension
(
extension
,
this
.
_configurationService
));
// remove non-UI extensions from the local extensions
localExtensions
=
localExtensions
.
filter
(
extension
=>
extension
.
isBuiltin
||
isUIExtension
(
extension
,
this
.
_configurationService
));
// in case of overlap, the remote wins
const
isRemoteExtension
=
new
Set
<
string
>
();
remoteEnv
.
extensions
.
forEach
(
extension
=>
isRemoteExtension
.
add
(
ExtensionIdentifier
.
toKey
(
extension
.
identifier
)));
localExtensions
=
localExtensions
.
filter
(
extension
=>
!
isRemoteExtension
.
has
(
ExtensionIdentifier
.
toKey
(
extension
.
identifier
)));
// compute enabled extensions
const
enabledExtensions
=
await
this
.
_getRuntimeExtensions
((
<
IExtensionDescription
[]
>
[]).
concat
(
remoteEnv
.
extensions
).
concat
(
localExtensions
));
// remove disabled extensions
const
isEnabled
=
new
Set
<
string
>
();
enabledExtensions
.
forEach
(
extension
=>
isEnabled
.
add
(
ExtensionIdentifier
.
toKey
(
extension
.
identifier
)));
remoteEnv
.
extensions
=
remoteEnv
.
extensions
.
filter
(
extension
=>
isEnabled
.
has
(
ExtensionIdentifier
.
toKey
(
extension
.
identifier
)));
localExtensions
=
localExtensions
.
filter
(
extension
=>
isEnabled
.
has
(
ExtensionIdentifier
.
toKey
(
extension
.
identifier
)));
// save for remote extension's init data
this
.
_remoteExtensionsEnvironmentData
.
set
(
remoteAuthority
,
remoteEnv
);
this
.
_handleExtensionPoints
(
enabledExtensions
);
extensionHost
.
start
(
localExtensions
.
map
(
extension
=>
extension
.
identifier
));
this
.
_releaseBarrier
();
}
else
{
await
this
.
_startLocalExtensionHost
(
extensionHost
,
localExtensions
);
}
}
private
async
_startLocalExtensionHost
(
extensionHost
:
ExtensionHostProcessManager
,
localExtensions
:
IExtensionDescription
[]):
Promise
<
void
>
{
const
enabledExtensions
=
await
this
.
_getRuntimeExtensions
(
localExtensions
);
this
.
_handleExtensionPoints
(
enabledExtensions
);
extensionHost
.
start
(
enabledExtensions
.
map
(
extension
=>
extension
.
identifier
).
filter
(
id
=>
this
.
_registry
.
containsExtension
(
id
)));
...
...
src/vs/workbench/services/extensions/electron-browser/remoteExtensionHostClient.ts
0 → 100644
浏览文件 @
8e89e343
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
ipcRenderer
as
ipc
}
from
'
electron
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
IMessagePassingProtocol
}
from
'
vs/base/parts/ipc/common/ipc
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
ILabelService
}
from
'
vs/platform/label/common/label
'
;
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
product
from
'
vs/platform/product/node/product
'
;
import
pkg
from
'
vs/platform/product/node/package
'
;
import
{
connectRemoteAgentExtensionHost
,
IRemoteExtensionHostStartParams
,
IConnectionOptions
}
from
'
vs/platform/remote/common/remoteAgentConnection
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
IWindowService
}
from
'
vs/platform/windows/common/windows
'
;
import
{
IWorkspaceContextService
,
WorkbenchState
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IInitData
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
MessageType
,
createMessageOfType
,
isMessageOfType
}
from
'
vs/workbench/services/extensions/common/extensionHostProtocol
'
;
import
{
IExtensionHostStarter
}
from
'
vs/workbench/services/extensions/common/extensions
'
;
import
{
parseExtensionDevOptions
}
from
'
vs/workbench/services/extensions/common/extensionDevOptions
'
;
import
{
IRemoteAgentEnvironment
}
from
'
vs/platform/remote/common/remoteAgentEnvironment
'
;
import
{
IRemoteAuthorityResolverService
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
PersistentProtocol
}
from
'
vs/base/parts/ipc/common/ipc.net
'
;
import
{
IExtensionDescription
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
VSBuffer
}
from
'
vs/base/common/buffer
'
;
import
{
nodeWebSocketFactory
}
from
'
vs/platform/remote/node/nodeWebSocketFactory
'
;
import
{
IExtensionHostDebugService
}
from
'
vs/workbench/services/extensions/common/extensionHostDebug
'
;
export
interface
IInitDataProvider
{
readonly
remoteAuthority
:
string
;
getInitData
():
Promise
<
IRemoteAgentEnvironment
>
;
}
export
class
RemoteExtensionHostClient
extends
Disposable
implements
IExtensionHostStarter
{
private
_onCrashed
:
Emitter
<
[
number
,
string
|
null
]
>
=
this
.
_register
(
new
Emitter
<
[
number
,
string
|
null
]
>
());
public
readonly
onCrashed
:
Event
<
[
number
,
string
|
null
]
>
=
this
.
_onCrashed
.
event
;
private
_protocol
:
PersistentProtocol
|
null
;
private
readonly
_isExtensionDevHost
:
boolean
;
private
readonly
_isExtensionDevTestFromCli
:
boolean
;
private
_terminating
:
boolean
;
constructor
(
private
readonly
_allExtensions
:
Promise
<
IExtensionDescription
[]
>
,
private
readonly
_initDataProvider
:
IInitDataProvider
,
@
IWorkspaceContextService
private
readonly
_contextService
:
IWorkspaceContextService
,
@
IEnvironmentService
private
readonly
_environmentService
:
IEnvironmentService
,
@
ITelemetryService
private
readonly
_telemetryService
:
ITelemetryService
,
@
IWindowService
private
readonly
_windowService
:
IWindowService
,
@
ILifecycleService
private
readonly
_lifecycleService
:
ILifecycleService
,
@
ILogService
private
readonly
_logService
:
ILogService
,
@
ILabelService
private
readonly
_labelService
:
ILabelService
,
@
IRemoteAuthorityResolverService
private
readonly
remoteAuthorityResolverService
:
IRemoteAuthorityResolverService
,
@
IExtensionHostDebugService
private
readonly
_extensionHostDebugService
:
IExtensionHostDebugService
)
{
super
();
this
.
_protocol
=
null
;
this
.
_terminating
=
false
;
this
.
_register
(
this
.
_lifecycleService
.
onShutdown
(
reason
=>
this
.
dispose
()));
const
devOpts
=
parseExtensionDevOptions
(
this
.
_environmentService
);
this
.
_isExtensionDevHost
=
devOpts
.
isExtensionDevHost
;
this
.
_isExtensionDevTestFromCli
=
devOpts
.
isExtensionDevTestFromCli
;
}
public
start
():
Promise
<
IMessagePassingProtocol
>
{
const
options
:
IConnectionOptions
=
{
isBuilt
:
this
.
_environmentService
.
isBuilt
,
commit
:
product
.
commit
,
webSocketFactory
:
nodeWebSocketFactory
,
addressProvider
:
{
getAddress
:
async
()
=>
{
const
{
host
,
port
}
=
await
this
.
remoteAuthorityResolverService
.
resolveAuthority
(
this
.
_initDataProvider
.
remoteAuthority
);
return
{
host
,
port
};
}
}
};
return
this
.
remoteAuthorityResolverService
.
resolveAuthority
(
this
.
_initDataProvider
.
remoteAuthority
).
then
((
resolvedAuthority
)
=>
{
const
startParams
:
IRemoteExtensionHostStartParams
=
{
language
:
platform
.
language
,
debugId
:
this
.
_environmentService
.
debugExtensionHost
.
debugId
,
break
:
this
.
_environmentService
.
debugExtensionHost
.
break
,
port
:
this
.
_environmentService
.
debugExtensionHost
.
port
,
};
const
extDevLocs
=
this
.
_environmentService
.
extensionDevelopmentLocationURI
;
let
debugOk
=
true
;
if
(
extDevLocs
&&
extDevLocs
.
length
>
0
)
{
// TODO@AW: handles only first path in array
if
(
extDevLocs
[
0
].
scheme
===
Schemas
.
file
)
{
debugOk
=
false
;
}
}
if
(
!
debugOk
)
{
startParams
.
break
=
false
;
}
return
connectRemoteAgentExtensionHost
(
options
,
startParams
).
then
(
result
=>
{
let
{
protocol
,
debugPort
}
=
result
;
const
isExtensionDevelopmentDebug
=
typeof
debugPort
===
'
number
'
;
if
(
debugOk
&&
this
.
_environmentService
.
isExtensionDevelopment
&&
this
.
_environmentService
.
debugExtensionHost
.
debugId
&&
debugPort
)
{
this
.
_extensionHostDebugService
.
attachSession
(
this
.
_environmentService
.
debugExtensionHost
.
debugId
,
debugPort
,
this
.
_initDataProvider
.
remoteAuthority
);
}
protocol
.
onClose
(()
=>
{
this
.
_onExtHostConnectionLost
();
});
protocol
.
onSocketClose
(()
=>
{
if
(
this
.
_isExtensionDevHost
)
{
this
.
_onExtHostConnectionLost
();
}
});
// 1) wait for the incoming `ready` event and send the initialization data.
// 2) wait for the incoming `initialized` event.
return
new
Promise
<
IMessagePassingProtocol
>
((
resolve
,
reject
)
=>
{
let
handle
=
setTimeout
(()
=>
{
reject
(
'
timeout
'
);
},
60
*
1000
);
const
disposable
=
protocol
.
onMessage
(
msg
=>
{
if
(
isMessageOfType
(
msg
,
MessageType
.
Ready
))
{
// 1) Extension Host is ready to receive messages, initialize it
this
.
_createExtHostInitData
(
isExtensionDevelopmentDebug
).
then
(
data
=>
protocol
.
send
(
VSBuffer
.
fromString
(
JSON
.
stringify
(
data
))));
return
;
}
if
(
isMessageOfType
(
msg
,
MessageType
.
Initialized
))
{
// 2) Extension Host is initialized
clearTimeout
(
handle
);
// stop listening for messages here
disposable
.
dispose
();
// release this promise
this
.
_protocol
=
protocol
;
resolve
(
protocol
);
return
;
}
console
.
error
(
`received unexpected message during handshake phase from the extension host: `
,
msg
);
});
});
});
});
}
private
_onExtHostConnectionLost
():
void
{
if
(
this
.
_terminating
)
{
// Expected termination path (we asked the process to terminate)
return
;
}
// Unexpected termination
if
(
!
this
.
_isExtensionDevHost
)
{
this
.
_onCrashed
.
fire
([
0
,
null
]);
}
// Expected development extension termination: When the extension host goes down we also shutdown the window
else
if
(
!
this
.
_isExtensionDevTestFromCli
)
{
this
.
_windowService
.
closeWindow
();
}
// When CLI testing make sure to exit with proper exit code
else
{
ipc
.
send
(
'
vscode:exit
'
,
0
);
}
}
private
_createExtHostInitData
(
isExtensionDevelopmentDebug
:
boolean
):
Promise
<
IInitData
>
{
return
Promise
.
all
([
this
.
_allExtensions
,
this
.
_telemetryService
.
getTelemetryInfo
(),
this
.
_initDataProvider
.
getInitData
()]).
then
(([
allExtensions
,
telemetryInfo
,
remoteExtensionHostData
])
=>
{
// Collect all identifiers for extension ids which can be considered "resolved"
const
resolvedExtensions
=
allExtensions
.
filter
(
extension
=>
!
extension
.
main
).
map
(
extension
=>
extension
.
identifier
);
const
hostExtensions
=
allExtensions
.
filter
(
extension
=>
extension
.
main
&&
extension
.
api
===
'
none
'
).
map
(
extension
=>
extension
.
identifier
);
const
workspace
=
this
.
_contextService
.
getWorkspace
();
const
r
:
IInitData
=
{
commit
:
product
.
commit
,
version
:
pkg
.
version
,
parentPid
:
remoteExtensionHostData
.
pid
,
environment
:
{
isExtensionDevelopmentDebug
,
appRoot
:
remoteExtensionHostData
.
appRoot
,
appSettingsHome
:
remoteExtensionHostData
.
appSettingsHome
,
appName
:
product
.
nameLong
,
appUriScheme
:
product
.
urlProtocol
,
appLanguage
:
platform
.
language
,
extensionDevelopmentLocationURI
:
this
.
_environmentService
.
extensionDevelopmentLocationURI
,
extensionTestsLocationURI
:
this
.
_environmentService
.
extensionTestsLocationURI
,
globalStorageHome
:
remoteExtensionHostData
.
globalStorageHome
,
userHome
:
remoteExtensionHostData
.
userHome
},
workspace
:
this
.
_contextService
.
getWorkbenchState
()
===
WorkbenchState
.
EMPTY
?
null
:
{
configuration
:
workspace
.
configuration
,
id
:
workspace
.
id
,
name
:
this
.
_labelService
.
getWorkspaceLabel
(
workspace
)
},
resolvedExtensions
:
resolvedExtensions
,
hostExtensions
:
hostExtensions
,
extensions
:
remoteExtensionHostData
.
extensions
,
telemetryInfo
,
logLevel
:
this
.
_logService
.
getLevel
(),
logsLocation
:
remoteExtensionHostData
.
extensionHostLogsPath
,
autoStart
:
true
,
remoteAuthority
:
this
.
_initDataProvider
.
remoteAuthority
,
};
return
r
;
});
}
getInspectPort
():
number
|
undefined
{
return
undefined
;
}
dispose
():
void
{
super
.
dispose
();
this
.
_terminating
=
true
;
if
(
this
.
_protocol
)
{
// Send the extension host a request to terminate itself
// (graceful termination)
const
socket
=
this
.
_protocol
.
getSocket
();
this
.
_protocol
.
send
(
createMessageOfType
(
MessageType
.
Terminate
));
this
.
_protocol
.
sendDisconnect
();
this
.
_protocol
.
dispose
();
socket
.
end
();
this
.
_protocol
=
null
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录