@@ -71,7 +71,7 @@ import { ObjectScriptRoutineSymbolProvider } from "./providers/ObjectScriptRouti
7171import { ObjectScriptCodeLensProvider } from "./providers/ObjectScriptCodeLensProvider" ;
7272import { XmlContentProvider } from "./providers/XmlContentProvider" ;
7373
74- import { AtelierAPI } from "./api" ;
74+ import { AtelierAPI , cookiesMap , logoutOfSessions } from "./api" ;
7575import { ObjectScriptDebugAdapterDescriptorFactory } from "./debug/debugAdapterFactory" ;
7676import { ObjectScriptConfigurationProvider } from "./debug/debugConfProvider" ;
7777import { ProjectsExplorerProvider } from "./explorer/projectsExplorer" ;
@@ -340,20 +340,16 @@ export function getResolvedConnectionSpec(key: string, dflt: any): any {
340340/** The `api.serverId`s of all servers that are known to be inactive */
341341export const inactiveServerIds : Set < string > = new Set ( ) ;
342342
343- export async function checkConnection (
344- clearCookies = false ,
345- uri ?: vscode . Uri ,
346- triggerRefreshes ?: boolean
347- ) : Promise < void > {
343+ export async function checkConnection ( clearState = false , uri ?: vscode . Uri , triggerRefreshes ?: boolean ) : Promise < void > {
348344 // Do nothing if already checking the connection
349345 if ( checkingConnection ) {
350346 return ;
351347 }
352348
353349 const { apiTarget, configName } = connectionTarget ( uri ) ;
354350 const wsKey = configName . toLowerCase ( ) ;
355- if ( clearCookies ) {
356- /// clean-up cached values
351+ if ( clearState ) {
352+ // clean-up cached values
357353 await workspaceState . update ( wsKey + ":host" , undefined ) ;
358354 await workspaceState . update ( wsKey + ":port" , undefined ) ;
359355 await workspaceState . update ( wsKey + ":superserverPort" , undefined ) ;
@@ -422,10 +418,6 @@ export async function checkConnection(
422418 }
423419 }
424420
425- if ( clearCookies ) {
426- api . clearCookies ( ) ;
427- }
428-
429421 // Before recreating the api object (in case something has updated connection details since we last fetched them?)
430422 // if this is an external server, remove it from the inactive list because its presence there would block the reconnect that we want to be attempting
431423 if ( api . externalServer ) {
@@ -1521,38 +1513,44 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
15211513 supportsMultipleEditorsPerDocument : false ,
15221514 } ) ,
15231515 vscode . workspace . onDidChangeConfiguration ( async ( { affectsConfiguration } ) => {
1524- if ( affectsConfiguration ( "objectscript.conn" ) || affectsConfiguration ( "intersystems.servers" ) ) {
1525- if ( affectsConfiguration ( "intersystems.servers" ) ) {
1526- // Gather the server names previously resolved
1527- const resolvedServers : string [ ] = [ ] ;
1528- resolvedConnSpecs . forEach ( ( v , k ) => resolvedServers . push ( k ) ) ;
1529- // Clear the cache
1530- resolvedConnSpecs . clear ( ) ;
1531- // Resolve them again, sequentially in case user needs to be prompted for credentials
1532- for await ( const serverName of resolvedServers ) {
1533- await resolveConnectionSpec ( serverName ) ;
1534- }
1535- }
1536- // Check connections sequentially for each workspace folder
1537- let refreshFilesExplorer = false ;
1538- for await ( const folder of vscode . workspace . workspaceFolders ?? [ ] ) {
1539- if ( schemas . includes ( folder . uri . scheme ) ) {
1540- refreshFilesExplorer = true ;
1541- }
1542- try {
1543- await checkConnection ( true , folder . uri , true ) ;
1544- } catch ( _ ) {
1545- continue ;
1546- }
1516+ // Loop through all ws folder connections and see if any changed
1517+ // Find all "sessions" that are new or orphaned.
1518+ // For new ones, establish a connection?
1519+ // For orphans, logout and clear the cookies.
1520+ let refreshFilesExplorer = false ;
1521+ const newConnections : Set < string > = new Set ( ) ;
1522+ const affectedWsFolders : vscode . WorkspaceFolder [ ] = [ ] ;
1523+ for ( const wsFolder of vscode . workspace . workspaceFolders ?? [ ] ) {
1524+ const api = new AtelierAPI ( wsFolder . uri ) ;
1525+ newConnections . add ( api . mapKey ( ) ) ;
1526+ const { serverName } = api . config ;
1527+ if (
1528+ ( notIsfs ( wsFolder . uri ) && affectsConfiguration ( "objectscript.conn" , wsFolder ) ) ||
1529+ ( serverName && affectsConfiguration ( `intersystems.servers.${ serverName } ` , wsFolder ) )
1530+ ) {
1531+ // Connection info changed
1532+ affectedWsFolders . push ( wsFolder ) ;
1533+ if ( filesystemSchemas . includes ( wsFolder . uri . scheme ) ) refreshFilesExplorer = true ;
15471534 }
1548- explorerProvider . refresh ( ) ;
1549- projectsExplorerProvider . refresh ( ) ;
1550- if ( refreshFilesExplorer ) {
1551- // This unavoidably switches to the File Explorer view, so only do it if isfs folders were found
1552- vscode . commands . executeCommand ( "workbench.files.action.refreshFilesExplorer" ) ;
1535+ }
1536+ // Log out of any sessions that are orphaned
1537+ logoutOfSessions ( Array . from ( cookiesMap . keys ( ) ) . filter ( ( k ) => ! newConnections . has ( k ) ) ) ;
1538+ // Update the connection info for affected workspace folders
1539+ // This should create new CSP sessions if needed
1540+ for ( const wsFolder of affectedWsFolders ) {
1541+ try {
1542+ await checkConnection ( true , wsFolder . uri , true ) ;
1543+ } catch {
1544+ // Errors are handled by checkConnection()
15531545 }
1554- updateWebAndAbstractDocsCaches ( vscode . workspace . workspaceFolders ) ;
15551546 }
1547+ explorerProvider . refresh ( ) ;
1548+ projectsExplorerProvider . refresh ( ) ;
1549+ if ( refreshFilesExplorer ) {
1550+ // This unavoidably switches to the File Explorer view, so only do it if isfs folders were found
1551+ vscode . commands . executeCommand ( "workbench.files.action.refreshFilesExplorer" ) ;
1552+ }
1553+ updateWebAndAbstractDocsCaches ( affectedWsFolders ) ;
15561554 if ( affectsConfiguration ( "objectscript.commentToken" ) ) {
15571555 // Update the language configuration for "objectscript" and "objectscript-macros"
15581556 macLangConf ?. dispose ( ) ;
@@ -2037,24 +2035,5 @@ export async function deactivate(): Promise<void> {
20372035 intLangConf ?. dispose ( ) ;
20382036 disposeDocumentIndex ( ) ;
20392037 // Log out of all CSP sessions
2040- const loggedOut : Set < string > = new Set ( ) ;
2041- const promises : Promise < any > [ ] = [ ] ;
2042- for ( const f of vscode . workspace . workspaceFolders ?? [ ] ) {
2043- const api = new AtelierAPI ( f . uri ) ;
2044- if ( ! api . active || ! api . cookies . length ) continue ;
2045- const sessionCookie = api . cookies . find ( ( c ) => c . startsWith ( "CSPSESSIONID-" ) ) ;
2046- if ( ! sessionCookie || loggedOut . has ( sessionCookie ) ) continue ;
2047- loggedOut . add ( sessionCookie ) ;
2048- promises . push (
2049- api . request (
2050- 0 ,
2051- "HEAD" ,
2052- undefined ,
2053- undefined ,
2054- // Prefer IRISLogout for servers that support it
2055- semver . lt ( api . config . serverVersion , "2018.2.0" ) ? { CacheLogout : "end" } : { IRISLogout : "end" }
2056- )
2057- ) ;
2058- }
2059- await Promise . allSettled ( promises ) ;
2038+ await logoutOfSessions ( ) ;
20602039}
0 commit comments