Perf: The first time that a ITypeProvider.Invalidate event is fired, the existing type providers instances are not disposed
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 131
Description
Whenever a ITypeProvider.Invalidate event is fired, all the ITypeProvider instances are discarded and new ones are created. Ideally only the one where Invalidate is being called should be created. In any case, the type provider implementation can workaround this be listening to the Disposing events. However, the first time it happens, the Disposing events are not triggered.
You can see the issue by compiling the current master branch of FSharp.Data and compiling FSharp.Data.DesignTime.dll with the LOGGING_ENABLED compilation symbol, and starting devenv file.fsx on a file with the following content, and then modify Metadata1.xml once, then modify Metadata1.xml again, then modify Metadata2.xml.
To repro the issue, open `devenv file.fsx` on this content:
#r "System.Xml.Linq"
#r "FSharp.Data.dll"
open FSharp.Data
type Schema1 = XmlProvider<"Metadata1.xml">
let schema1 = Schema1.GetSample()
type Schema2 = XmlProvider<"Metadata2.xml">
let schema2 = Schema2.GetSample()
type Schema3 = XmlProvider<"Metadata2.xml", Global=true>
let schema3 = Schema3.GetSample()
let wb = WorldBankData.GetDataContext()
type WB = WorldBankDataProvider
let wb2 = WB.GetDataContext()
On the log output, you can see on the 3 file edit operations, new instances of all type providers were created. On the first time, the two WorldBank type providers had to be fully recalculated, and the type provider instances 0 to 4 never got the finalizer called, which indicates they were never GC'ed. On the second and third time however, the type provider was able to take advantage of the Disposing event to cache things temporarily, so only the type provider calculation for the affected files were done, and the previous type provider instances were GC'ed correctly:
Creating TypeProviderForNamespaces ProviderImplementation.JsonProvider [0]
Creating TypeProviderForNamespaces ProviderImplementation.XmlProvider [1]
Creating TypeProviderForNamespaces ProviderImplementation.CsvProvider [2]
Creating TypeProviderForNamespaces ProviderImplementation.WorldBankProvider [3]
GeneratingProvidedType WorldBankData [3]
Caching for 10 seconds
Setting up dispose action
Finished GeneratingProvidedType [4ms]
Creating TypeProviderForNamespaces ProviderImplementation.HtmlProvider [4]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [1]
LoadingSample Metadata1.xml
Parsing Metadata1.xml
Finished Parsing [8ms]
Finished LoadingSample [92ms]
Inference Metadata1.xml
Finished Inference [463ms]
TypeGeneration Metadata1.xml
Finished TypeGeneration [182ms]
CommonTypeGeneration Metadata1.xml
Finished CommonTypeGeneration [14ms]
Caching for 10 seconds
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata1.xml watcher
Finished GeneratingProvidedType [1217ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [69ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [23ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [8ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [53ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [1]
LoadingSample Metadata2.xml
Parsing Metadata2.xml
Finished Parsing [4ms]
Finished LoadingSample [83ms]
Inference Metadata2.xml
Finished Inference [224ms]
TypeGeneration Metadata2.xml
Finished TypeGeneration [5ms]
CommonTypeGeneration Metadata2.xml
Finished CommonTypeGeneration [0ms]
Caching for 10 seconds
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [555ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [35ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [1]
LoadingSample Metadata2.xml
Parsing Metadata2.xml
Finished Parsing [9ms]
Finished LoadingSample [56ms]
Inference Metadata2.xml
Finished Inference [407ms]
TypeGeneration Metadata2.xml
Finished TypeGeneration [3ms]
CommonTypeGeneration Metadata2.xml
Finished CommonTypeGeneration [0ms]
Caching for 10 seconds
Setting up dispose action
Reusing C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [646ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [1]
Retrieved from cache
Finished GeneratingProvidedType [5ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [1]
Retrieved from cache
Finished GeneratingProvidedType [29ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [3]
Caching for 10 seconds
Setting up dispose action
Finished GeneratingProvidedType [2ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [3]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [3]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [23ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [1]
Retrieved from cache
Finished GeneratingProvidedType [10ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [1]
Retrieved from cache
Finished GeneratingProvidedType [14ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [1]
Retrieved from cache
Finished GeneratingProvidedType [14ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [3]
Retrieved from cache
Finished GeneratingProvidedType [3ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [3]
Retrieved from cache
Finished GeneratingProvidedType [4ms]
Cache expired: WorldBankData
Cache expired: XmlProvider,Sample="Metadata1.xml"
Cache expired: XmlProvider,Sample="Metadata2.xml"
Cache expired: XmlProvider,Sample="Metadata2.xml",Global="True"
Cache expired: WorldBankDataProvider,Asynchronous="True"
File changed: C:\Users\guguer\Desktop\Metadata1.xml
InvalidateOneType XmlProvider,Sample="Metadata1.xml" in ProviderImplementation.XmlProvider [1]
Unsubscribed XmlProvider,Sample="Metadata2.xml",Global="True" [1] from C:\Users\guguer\Desktop\Metadata2.xml watcher
Caching XmlProvider,Sample="Metadata2.xml",Global="True" [1] for 10 seconds
Unsubscribed XmlProvider,Sample="Metadata2.xml" [1] from C:\Users\guguer\Desktop\Metadata2.xml watcher
Disposing C:\Users\guguer\Desktop\Metadata2.xml watcher
Caching XmlProvider,Sample="Metadata2.xml" [1] for 10 seconds
Unsubscribed XmlProvider,Sample="Metadata1.xml" [1] from C:\Users\guguer\Desktop\Metadata1.xml watcher
Disposing C:\Users\guguer\Desktop\Metadata1.xml watcher
Dropping dispose action for XmlProvider,Sample="Metadata1.xml" [1]
Calling invalidate for ProviderImplementation.XmlProvider [1]
Finished InvalidateOneType [39ms]
Creating TypeProviderForNamespaces ProviderImplementation.JsonProvider [5]
Creating TypeProviderForNamespaces ProviderImplementation.XmlProvider [6]
Creating TypeProviderForNamespaces ProviderImplementation.CsvProvider [7]
Creating TypeProviderForNamespaces ProviderImplementation.WorldBankProvider [8]
GeneratingProvidedType WorldBankData [8]
Caching for 10 seconds
Setting up dispose action
Finished GeneratingProvidedType [4ms]
Creating TypeProviderForNamespaces ProviderImplementation.HtmlProvider [9]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [6]
LoadingSample Metadata1.xml
Parsing Metadata1.xml
Finished Parsing [8ms]
Finished LoadingSample [127ms]
Inference Metadata1.xml
Finished Inference [161ms]
TypeGeneration Metadata1.xml
Finished TypeGeneration [2ms]
CommonTypeGeneration Metadata1.xml
Finished CommonTypeGeneration [0ms]
Caching for 10 seconds
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata1.xml watcher
Finished GeneratingProvidedType [312ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [6]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [6]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [6]
Retrieved from cache
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [6ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [6]
Retrieved from cache
Finished GeneratingProvidedType [5ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [6]
Retrieved from cache
Finished GeneratingProvidedType [7ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [6]
Retrieved from cache
Setting up dispose action
Reusing C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [5ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [6]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [6]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [8]
Caching for 10 seconds
Setting up dispose action
Finished GeneratingProvidedType [4ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [8]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [8]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
Cache expired: XmlProvider,Sample="Metadata2.xml",Global="True"
Cache expired: XmlProvider,Sample="Metadata2.xml"
Cache expired: WorldBankData
Cache expired: XmlProvider,Sample="Metadata1.xml"
Cache expired: WorldBankDataProvider,Asynchronous="True"
File changed: C:\Users\guguer\Desktop\Metadata1.xml
InvalidateOneType XmlProvider,Sample="Metadata1.xml" in ProviderImplementation.XmlProvider [6]
Unsubscribed XmlProvider,Sample="Metadata2.xml",Global="True" [6] from C:\Users\guguer\Desktop\Metadata2.xml watcher
Caching XmlProvider,Sample="Metadata2.xml",Global="True" [6] for 10 seconds
Unsubscribed XmlProvider,Sample="Metadata2.xml" [6] from C:\Users\guguer\Desktop\Metadata2.xml watcher
Disposing C:\Users\guguer\Desktop\Metadata2.xml watcher
Caching XmlProvider,Sample="Metadata2.xml" [6] for 10 seconds
Unsubscribed XmlProvider,Sample="Metadata1.xml" [6] from C:\Users\guguer\Desktop\Metadata1.xml watcher
Disposing C:\Users\guguer\Desktop\Metadata1.xml watcher
Dropping dispose action for XmlProvider,Sample="Metadata1.xml" [6]
Calling invalidate for ProviderImplementation.XmlProvider [6]
Finished InvalidateOneType [13ms]
DisposingEvent ProviderImplementation.HtmlProvider [9]
Finished DisposingEvent [0ms]
DisposingEvent ProviderImplementation.WorldBankProvider [8]
Caching WorldBankDataProvider,Asynchronous="True" [8] for 10 seconds
Caching WorldBankData [8] for 10 seconds
Finished DisposingEvent [2ms]
DisposingEvent ProviderImplementation.CsvProvider [7]
Finished DisposingEvent [0ms]
DisposingEvent ProviderImplementation.XmlProvider [6]
Caching XmlProvider,Sample="Metadata2.xml",Global="True" [6] for 10 seconds
Caching XmlProvider,Sample="Metadata2.xml" [6] for 10 seconds
Finished DisposingEvent [1ms]
DisposingEvent ProviderImplementation.JsonProvider [5]
Finished DisposingEvent [0ms]
Creating TypeProviderForNamespaces ProviderImplementation.JsonProvider [10]
Creating TypeProviderForNamespaces ProviderImplementation.XmlProvider [11]
Finalize ProviderImplementation.HtmlProvider [9]
Finalize ProviderImplementation.CsvProvider [7]
Finalize ProviderImplementation.XmlProvider [6]
Finalize ProviderImplementation.JsonProvider [5]
Creating TypeProviderForNamespaces ProviderImplementation.CsvProvider [12]
Creating TypeProviderForNamespaces ProviderImplementation.WorldBankProvider [13]
GeneratingProvidedType WorldBankData [13]
Retrieved from cache
Setting up dispose action
Finished GeneratingProvidedType [2ms]
Creating TypeProviderForNamespaces ProviderImplementation.HtmlProvider [14]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [11]
LoadingSample Metadata1.xml
Parsing Metadata1.xml
Finished Parsing [2ms]
Finished LoadingSample [13ms]
Inference Metadata1.xml
Finished Inference [174ms]
TypeGeneration Metadata1.xml
Finished TypeGeneration [6ms]
CommonTypeGeneration Metadata1.xml
Finished CommonTypeGeneration [0ms]
Caching for 10 seconds
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata1.xml watcher
Finished GeneratingProvidedType [282ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [11]
Retrieved from cache
Finished GeneratingProvidedType [4ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [11]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [11]
Retrieved from cache
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [13ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [11]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [11]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [11]
Retrieved from cache
Setting up dispose action
Reusing C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [3ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [11]
Retrieved from cache
Finished GeneratingProvidedType [3ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [11]
Retrieved from cache
Finished GeneratingProvidedType [14ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [13]
Retrieved from cache
Setting up dispose action
Finished GeneratingProvidedType [4ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [13]
Retrieved from cache
Finished GeneratingProvidedType [4ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [13]
Retrieved from cache
Finished GeneratingProvidedType [36ms]
Cache expired: WorldBankDataProvider,Asynchronous="True"
Cache expired: WorldBankData
Cache expired: XmlProvider,Sample="Metadata2.xml"
Cache expired: XmlProvider,Sample="Metadata2.xml",Global="True"
Cache expired: XmlProvider,Sample="Metadata1.xml"
File changed: C:\Users\guguer\Desktop\Metadata2.xml
InvalidateOneType XmlProvider,Sample="Metadata2.xml" in ProviderImplementation.XmlProvider [11]
Unsubscribed XmlProvider,Sample="Metadata2.xml",Global="True" [11] from C:\Users\guguer\Desktop\Metadata2.xml watcher
Caching XmlProvider,Sample="Metadata2.xml",Global="True" [11] for 10 seconds
Unsubscribed XmlProvider,Sample="Metadata2.xml" [11] from C:\Users\guguer\Desktop\Metadata2.xml watcher
Disposing C:\Users\guguer\Desktop\Metadata2.xml watcher
Dropping dispose action for XmlProvider,Sample="Metadata2.xml" [11]
Unsubscribed XmlProvider,Sample="Metadata1.xml" [11] from C:\Users\guguer\Desktop\Metadata1.xml watcher
Disposing C:\Users\guguer\Desktop\Metadata1.xml watcher
Caching XmlProvider,Sample="Metadata1.xml" [11] for 10 seconds
Calling invalidate for ProviderImplementation.XmlProvider [11]
Finished InvalidateOneType [9ms]
InvalidateOneType XmlProvider,Sample="Metadata2.xml",Global="True" in ProviderImplementation.XmlProvider [11]
Explicitly removed from cache: XmlProvider,Sample="Metadata2.xml",Global="True"
Dropping dispose action for XmlProvider,Sample="Metadata2.xml",Global="True" [11]
Caching XmlProvider,Sample="Metadata1.xml" [11] for 10 seconds
Calling invalidate for ProviderImplementation.XmlProvider [11]
Finished InvalidateOneType [3ms]
DisposingEvent ProviderImplementation.HtmlProvider [14]
Finished DisposingEvent [0ms]
DisposingEvent ProviderImplementation.WorldBankProvider [13]
Caching WorldBankDataProvider,Asynchronous="True" [13] for 10 seconds
Caching WorldBankData [13] for 10 seconds
Finished DisposingEvent [1ms]
DisposingEvent ProviderImplementation.CsvProvider [12]
Finished DisposingEvent [0ms]
DisposingEvent ProviderImplementation.XmlProvider [11]
Caching XmlProvider,Sample="Metadata1.xml" [11] for 10 seconds
Finished DisposingEvent [0ms]
DisposingEvent ProviderImplementation.JsonProvider [10]
Finished DisposingEvent [0ms]
Creating TypeProviderForNamespaces ProviderImplementation.JsonProvider [15]
Finalize ProviderImplementation.CsvProvider [12]
Finalize ProviderImplementation.WorldBankProvider [13]
Finalize ProviderImplementation.JsonProvider [10]
Finalize ProviderImplementation.HtmlProvider [14]
Creating TypeProviderForNamespaces ProviderImplementation.XmlProvider [16]
Creating TypeProviderForNamespaces ProviderImplementation.CsvProvider [17]
Creating TypeProviderForNamespaces ProviderImplementation.WorldBankProvider [18]
GeneratingProvidedType WorldBankData [18]
Retrieved from cache
Setting up dispose action
Finished GeneratingProvidedType [1ms]
Creating TypeProviderForNamespaces ProviderImplementation.HtmlProvider [19]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [16]
Retrieved from cache
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata1.xml watcher
Finished GeneratingProvidedType [2ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [16]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType XmlProvider,Sample="Metadata1.xml" [16]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [16]
LoadingSample Metadata2.xml
Parsing Metadata2.xml
Finished Parsing [2ms]
Finished LoadingSample [8ms]
Inference Metadata2.xml
Finished Inference [198ms]
TypeGeneration Metadata2.xml
Finished TypeGeneration [3ms]
CommonTypeGeneration Metadata2.xml
Finished CommonTypeGeneration [0ms]
Caching for 10 seconds
Setting up dispose action
Setting up C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [239ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [16]
Retrieved from cache
Finished GeneratingProvidedType [1ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml" [16]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [16]
LoadingSample Metadata2.xml
Parsing Metadata2.xml
Finished Parsing [8ms]
Finished LoadingSample [15ms]
Inference Metadata2.xml
Finished Inference [279ms]
TypeGeneration Metadata2.xml
Finished TypeGeneration [2ms]
CommonTypeGeneration Metadata2.xml
Finished CommonTypeGeneration [0ms]
Caching for 10 seconds
Setting up dispose action
Reusing C:\Users\guguer\Desktop\Metadata2.xml watcher
Finished GeneratingProvidedType [335ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [16]
Retrieved from cache
Finished GeneratingProvidedType [5ms]
GeneratingProvidedType XmlProvider,Sample="Metadata2.xml",Global="True" [16]
Retrieved from cache
Finished GeneratingProvidedType [2ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [18]
Retrieved from cache
Setting up dispose action
Finished GeneratingProvidedType [2ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [18]
Retrieved from cache
Finished GeneratingProvidedType [3ms]
GeneratingProvidedType WorldBankDataProvider,Asynchronous="True" [18]
Retrieved from cache
Finished GeneratingProvidedType [0ms]
Cache expired: WorldBankData
Cache expired: WorldBankDataProvider,Asynchronous="True"
Cache expired: XmlProvider,Sample="Metadata1.xml"
Cache expired: XmlProvider,Sample="Metadata2.xml"
Cache expired: XmlProvider,Sample="Metadata2.xml",Global="True"
// Closing VS:
Finalize ProviderImplementation.HtmlProvider [19]
Finalize ProviderImplementation.CsvProvider [17]
Finalize ProviderImplementation.WorldBankProvider [18]
Finalize ProviderImplementation.XmlProvider [16]
Finalize ProviderImplementation.JsonProvider [15]
Finalize ProviderImplementation.XmlProvider [11]
Finalize ProviderImplementation.HtmlProvider [4]
Finalize ProviderImplementation.WorldBankProvider [3]
Finalize ProviderImplementation.WorldBankProvider [8]
Finalize ProviderImplementation.JsonProvider [0]
Finalize ProviderImplementation.XmlProvider [1]
Finalize ProviderImplementation.CsvProvider [2]
(Sorry, this is a little verbose, but I think it was the best way to fully illustrate the problem)
Contributor guide
Assessment
This issue has not been assessed yet.