Skip to content

Commit

Permalink
Fixing fsac stalls (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheAngryByrd committed Mar 16, 2021
1 parent de72cf2 commit 7cac223
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 111 deletions.
217 changes: 109 additions & 108 deletions src/Ionide.ProjInfo.ProjectSystem/ProjectSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -
let loadProjects (projs: list<string * bool>) =
let gbs, nonGbs = projs |> List.partition (snd) |> fun (a, b) -> (a |> List.map fst, b |> List.map fst)
projs |> List.iter (fun (fileName, _) -> fileName |> ProjectResponse.ProjectChanged |> notify.Trigger)
x.LoadWorkspace(gbs, true)
x.LoadWorkspace(nonGbs, false)

if gbs |> Seq.isEmpty |> not then
x.LoadWorkspace(gbs, true)

if nonGbs |> Seq.isEmpty |> not then
x.LoadWorkspace(nonGbs, false)

projectsChanged |> deduplicateBy fst |> Observable.subscribe (loadProjects)

Expand All @@ -87,112 +91,109 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -

member private x.loadProjects (files: string list) (generateBinlog: bool) =
async {
if files |> Seq.isEmpty then
return false
else
let onChange fn =
projectsChanged.OnNext(fn, generateBinlog)

let onLoaded p =
match p with
| ProjectSystemState.Loading projectFileName -> ProjectResponse.ProjectLoading projectFileName |> notify.Trigger
| ProjectSystemState.Failed (projectFileName, error) -> ProjectResponse.ProjectError(projectFileName, error) |> notify.Trigger
| ProjectSystemState.Loaded (opts, extraInfo, projectFiles, isFromCache) ->
let response = ProjectCrackerCache.create (opts, extraInfo, projectFiles)
let projectFileName = response.ProjectFileName

let project =
match projects.TryFind projectFileName with
| Some prj -> prj
| None ->
let proj = new Project(projectFileName, onChange)
projects.[projectFileName] <- proj
proj

project.Response <- Some response

updateState response

let responseFiles =
response.Items
|> List.choose
(function
| ProjectViewerItem.Compile (p, _) -> Some p)

let projInfo : ProjectResult =
{ ProjectFileName = projectFileName
ProjectFiles = responseFiles
OutFileOpt = response.OutFile
References = response.References
Extra = response.ExtraInfo
ProjectItems = projectFiles
Additionals = Map.empty }

ProjectResponse.Project(projInfo, isFromCache) |> notify.Trigger
| ProjectSystemState.LoadedOther (extraInfo, projectFiles, fromDpiCache) ->
let responseFiles =
projectFiles
|> List.choose
(function
| ProjectViewerItem.Compile (p, _) -> Some p)

let projInfo : ProjectResult =
{ ProjectFileName = extraInfo.ProjectFileName
ProjectFiles = responseFiles
OutFileOpt = Some(extraInfo.TargetPath)
References = FscArguments.references extraInfo.OtherOptions
Extra = extraInfo
ProjectItems = projectFiles
Additionals = Map.empty }

ProjectResponse.Project(projInfo, fromDpiCache) |> notify.Trigger


//TODO check full path
let projectFileNames = files |> List.map Path.GetFullPath

let prjs = projectFileNames |> List.map (fun projectFileName -> projectFileName, new Project(projectFileName, onChange))

for projectFileName, proj in prjs do
projects.[projectFileName] <- proj


ProjectResponse.WorkspaceLoad false |> notify.Trigger
// this is to delay the project loading notification (of this thread)
// after the workspaceload started response returned below in outer async
// Make test output repeteable, and notification in correct order
match Environment.workspaceLoadDelay () with
| delay when delay > TimeSpan.Zero -> do! Async.Sleep(Environment.workspaceLoadDelay().TotalMilliseconds |> int)
| _ -> ()

let loader = workspaceLoaderFactory toolsPath

let bindNewOnloaded (n: WorkspaceProjectState) : ProjectSystemState option =
match n with
| WorkspaceProjectState.Loading (path) -> Some(ProjectSystemState.Loading path)
| WorkspaceProjectState.Loaded (opts, allKNownProjects, isFromCache) ->
let fcsOpts = FCS.mapToFSharpProjectOptions opts allKNownProjects

match Workspace.extractOptionsDPW fcsOpts with
| Ok optsDPW ->
let view = ProjectViewer.render optsDPW
Some(ProjectSystemState.Loaded(fcsOpts, optsDPW, view.Items, isFromCache))
| Error e -> Some(ProjectSystemState.Failed(e.ProjFile, e))

| WorkspaceProjectState.Failed (path, e) ->
let error = e
Some(ProjectSystemState.Failed(path, error))

// loader.Notifications.Add(fun arg -> arg |> bindNewOnloaded |> Option.iter onLoaded)

Workspace.loadInBackground onLoaded loader (prjs |> List.map snd) generateBinlog

ProjectResponse.WorkspaceLoad true |> notify.Trigger

isWorkspaceReady <- true
workspaceReady.Trigger()

return true
let onChange fn =
projectsChanged.OnNext(fn, generateBinlog)

let onLoaded p =
match p with
| ProjectSystemState.Loading projectFileName -> ProjectResponse.ProjectLoading projectFileName |> notify.Trigger
| ProjectSystemState.Failed (projectFileName, error) -> ProjectResponse.ProjectError(projectFileName, error) |> notify.Trigger
| ProjectSystemState.Loaded (opts, extraInfo, projectFiles, isFromCache) ->
let response = ProjectCrackerCache.create (opts, extraInfo, projectFiles)
let projectFileName = response.ProjectFileName

let project =
match projects.TryFind projectFileName with
| Some prj -> prj
| None ->
let proj = new Project(projectFileName, onChange)
projects.[projectFileName] <- proj
proj

project.Response <- Some response

updateState response

let responseFiles =
response.Items
|> List.choose
(function
| ProjectViewerItem.Compile (p, _) -> Some p)

let projInfo : ProjectResult =
{ ProjectFileName = projectFileName
ProjectFiles = responseFiles
OutFileOpt = response.OutFile
References = response.References
Extra = response.ExtraInfo
ProjectItems = projectFiles
Additionals = Map.empty }

ProjectResponse.Project(projInfo, isFromCache) |> notify.Trigger
| ProjectSystemState.LoadedOther (extraInfo, projectFiles, fromDpiCache) ->
let responseFiles =
projectFiles
|> List.choose
(function
| ProjectViewerItem.Compile (p, _) -> Some p)

let projInfo : ProjectResult =
{ ProjectFileName = extraInfo.ProjectFileName
ProjectFiles = responseFiles
OutFileOpt = Some(extraInfo.TargetPath)
References = FscArguments.references extraInfo.OtherOptions
Extra = extraInfo
ProjectItems = projectFiles
Additionals = Map.empty }

ProjectResponse.Project(projInfo, fromDpiCache) |> notify.Trigger


//TODO check full path
let projectFileNames = files |> List.map Path.GetFullPath

let prjs = projectFileNames |> List.map (fun projectFileName -> projectFileName, new Project(projectFileName, onChange))

for projectFileName, proj in prjs do
projects.[projectFileName] <- proj


ProjectResponse.WorkspaceLoad false |> notify.Trigger
// this is to delay the project loading notification (of this thread)
// after the workspaceload started response returned below in outer async
// Make test output repeteable, and notification in correct order
match Environment.workspaceLoadDelay () with
| delay when delay > TimeSpan.Zero -> do! Async.Sleep(Environment.workspaceLoadDelay().TotalMilliseconds |> int)
| _ -> ()

let loader = workspaceLoaderFactory toolsPath

let bindNewOnloaded (n: WorkspaceProjectState) : ProjectSystemState option =
match n with
| WorkspaceProjectState.Loading (path) -> Some(ProjectSystemState.Loading path)
| WorkspaceProjectState.Loaded (opts, allKNownProjects, isFromCache) ->
let fcsOpts = FCS.mapToFSharpProjectOptions opts allKNownProjects

match Workspace.extractOptionsDPW fcsOpts with
| Ok optsDPW ->
let view = ProjectViewer.render optsDPW
Some(ProjectSystemState.Loaded(fcsOpts, optsDPW, view.Items, isFromCache))
| Error e -> Some(ProjectSystemState.Failed(e.ProjFile, e))

| WorkspaceProjectState.Failed (path, e) ->
let error = e
Some(ProjectSystemState.Failed(path, error))

// loader.Notifications.Add(fun arg -> arg |> bindNewOnloaded |> Option.iter onLoaded)

Workspace.loadInBackground onLoaded loader (prjs |> List.map snd) generateBinlog

ProjectResponse.WorkspaceLoad true |> notify.Trigger

isWorkspaceReady <- true
workspaceReady.Trigger()

return true
}

member private x.LoaderLoop =
Expand Down
4 changes: 1 addition & 3 deletions src/Ionide.ProjInfo/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath) =
let loggers = ProjectLoader.createLoggers allKnownNames generateBinlog sw
bm.BeginBuild(new BuildParameters(Loggers = loggers))
let result = bm.BuildRequest gbr
let foo = bm.PendBuildRequest(gbr)

bm.EndBuild()

Expand All @@ -453,9 +452,8 @@ type WorkspaceLoaderViaProjectGraph private (toolsPath: ToolsPath) =
resultsByNode
|> Seq.map
(fun p ->
let foo = ProjectLoader.LoadedProject p.ProjectInstance

p.ProjectInstance.FullPath, ProjectLoader.getLoadedProjectInfo p.ProjectInstance.FullPath customProperties foo)
p.ProjectInstance.FullPath, ProjectLoader.getLoadedProjectInfo p.ProjectInstance.FullPath customProperties (ProjectLoader.LoadedProject p.ProjectInstance))

|> Seq.choose
(fun (projectPath, projectOptionResult) ->
Expand Down

0 comments on commit 7cac223

Please sign in to comment.