Skip to content

Commit

Permalink
Loading same project multiple times at same time
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzysztof-Cieslak committed Dec 22, 2020
1 parent 474080e commit 830caa2
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ _Pvt_Extensions
msbuild.binlog
/test/testrun_ws_fcs/
/.ionide/
/build

.fake
.ionide
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.45.1-preview03] - 2020-12-21

### Fixed

- Fixed a bug with loading same project multiple times at the same time.


## [0.45.0] - 2020-12-19

### Changed
Expand Down
9 changes: 9 additions & 0 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ Target.create
"Test"
(fun _ -> exec "dotnet" @"run --project .\test\Ionide.ProjInfo.Tests\Ionide.ProjInfo.Tests.fsproj" ".")

Target.create
"BuildRelease"
(fun _ ->
DotNet.build
(fun p ->
{ p with
Configuration = DotNet.BuildConfiguration.Release
OutputPath = Some buildDir })
"ionide-proj-info.sln")

// --------------------------------------------------------------------------------------
// Release Targets
Expand Down
23 changes: 17 additions & 6 deletions src/Ionide.ProjInfo.ProjectSystem/ProjectSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,26 @@ type ProjectController(toolsPath: ToolsPath) =

member private x.LoaderLoop =
MailboxProcessor.Start
(fun agent ->
let rec loop () =
(fun agent -> //If couldn't recive new event in 50 ms then just load previous one
let rec loop (previousStatus: (string list * bool) option) =
async {
let! (fn, gb) = agent.Receive()
let! _ = x.loadProjects fn gb
return ()
match previousStatus with
| Some (fn, gb) ->
match! agent.TryReceive(50) with
| None -> //If couldn't recive new event in 50 ms then just load previous one
let! _ = x.loadProjects fn gb
return! loop None
| Some (fn2, gb2) when fn2 = fn -> //If recived same load request then wait again (in practice shouldn't happen more than 2 times)
return! loop previousStatus
| Some (fn2, gb2) -> //If recived some other project load previous one, and then wait with the new one
let! _ = x.loadProjects fn gb
return! loop (Some(fn2, gb2))
| None ->
let! (fn, gb) = agent.Receive()
return! loop (Some(fn, gb))
}

loop ())
loop None)

///Event notifies that whole workspace has been loaded
member __.WorkspaceReady = workspaceReady.Publish
Expand Down
50 changes: 29 additions & 21 deletions src/Ionide.ProjInfo/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,33 @@ type WorkspaceLoader private (toolsPath: ToolsPath) =
let getAllKnonw () =
cache |> Seq.map (fun n -> n.Value) |> Seq.toList

let rec loadProject p =
let res = ProjectLoader.getProjectInfo p toolsPath customProperties

match res with
| Ok project ->
try
cache.Add(p, project)
let lst = project.ReferencedProjects |> Seq.map (fun n -> n.ProjectFileName) |> Seq.toList
let info = Some project
lst, info
with exc ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, GenericError(p, exc.Message)))
[], None
| Error msg when msg.Contains "The project file could not be loaded." ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, ProjectNotFound(p)))
[], None
| Error msg when msg.Contains "not restored" ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, ProjectNotRestored(p)))
[], None
| Error msg when msg.Contains "The operation cannot be completed because a build is already in progress." ->
//Try to load project again
Threading.Thread.Sleep(50)
loadProject p
| Error msg ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, GenericError(p, msg)))
[], None

let rec loadProjectList (projectList: string list) =
for p in projectList do
let newList, toTrigger =
Expand All @@ -342,27 +369,8 @@ type WorkspaceLoader private (toolsPath: ToolsPath) =
lst, None
else
loadingNotification.Trigger(WorkspaceProjectState.Loading p)
let res = ProjectLoader.getProjectInfo p toolsPath customProperties

match res with
| Ok project ->
try
cache.Add(p, project)
let lst = project.ReferencedProjects |> Seq.map (fun n -> n.ProjectFileName) |> Seq.toList
let info = Some project
lst, info
with exc ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, GenericError(p, exc.Message)))
[], None
| Error msg when msg.Contains "The project file could not be loaded." ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, ProjectNotFound(p)))
[], None
| Error msg when msg.Contains "not restored" ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, ProjectNotRestored(p)))
[], None
| Error msg ->
loadingNotification.Trigger(WorkspaceProjectState.Failed(p, GenericError(p, msg)))
[], None
loadProject p


loadProjectList newList

Expand Down

0 comments on commit 830caa2

Please sign in to comment.