wrath16 / MapPartyAssist

FFXIV Dalamud plugin for keeping track of treasure maps.
MIT License
5 stars 1 forks source link

plugin fails to load when multiple instances of xiv are open #3

Open Jaksuhn opened 12 months ago

Jaksuhn commented 12 months ago

weirdly it seems whenever a new instance of xiv is loaded, that one gets priority, and causes previously loaded instances to fail.

00:07:03.054 | ERR [PROFMAN] Couldn't apply state for one or more plugins
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.IO.IOException: The process cannot access the file 'C:\Users\snow\AppData\Roaming\XIVLauncher\pluginConfigs\MapPartyAssist\data.db' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at LiteDB.Engine.FileStreamFactory.GetStream(Boolean canWrite, Boolean sequencial)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at LiteDB.Engine.DiskService..ctor(EngineSettings settings, Int32[] memorySegmentSizes)
   at LiteDB.Engine.LiteEngine..ctor(EngineSettings settings)
   at LiteDB.ConnectionString.CreateEngine()
   at LiteDB.LiteDatabase..ctor(ConnectionString connectionString, BsonMapper mapper)
   at MapPartyAssist.Services.StorageManager..ctor(Plugin plugin, String path) in D:\Documents\Documents\Development\Visual Studio\MapPartyAssist\MapPartyAssist\Services\StorageManager.cs:line 31
   at MapPartyAssist.Plugin..ctor(DalamudPluginInterface pluginInterface, CommandManager commandManager, DataManager dataManager, ClientState clientState, Condition condition, DutyState dutyState, PartyList partyList, ChatGui chatGui, GameGui gameGui, Framework framework) in D:\Documents\Documents\Development\Visual Studio\MapPartyAssist\MapPartyAssist\Plugin.cs:line 117
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.ConstructorInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.ConstructorInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   at System.Reflection.RuntimeConstructorInfo.InvokeWithManyArguments(RuntimeConstructorInfo ci, Int32 argCount, Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeConstructorInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Dalamud.IoC.Internal.ServiceContainer.CreateAsync(Type objectType, Object[] scopedObjects, IServiceScope scope) in C:\goatsoft\companysecrets\dalamud\IoC\Internal\ServiceContainer.cs:line 137
   at Dalamud.Plugin.Internal.Types.LocalPlugin.LoadAsync(PluginLoadReason reason, Boolean reloading) in C:\goatsoft\companysecrets\dalamud\Plugin\Internal\Types\LocalPlugin.cs:line 526
   at Dalamud.Plugin.Internal.Profiles.ProfileManager.ApplyAllWantStatesAsync() in C:\goatsoft\companysecrets\dalamud\Plugin\Internal\Profiles\ProfileManager.cs:line 246
wrath16 commented 12 months ago

The database file can only be opened by one process at a time but that is strange that the original instance gets bumped. Does the second instance initialize okay? Might have to do with something internal to how Dalamud handles multiple instances. Will have to investigate further.

I'm also pushing an update soon that will properly release the lock on the database when the plugin fails to load.

wrath16 commented 12 months ago

Did some testing on my dev build and the second instance fails to start without affecting the first instance. For now I'd like to keep it so you can only have one instance active, not just because of the db lock restriction but also because things could get complicated with double-counting. You should be able to turn it off on one instance and enable in the other.

Looking at your stack trace it seems like a plugin collection was enabled and it's possible that that a previous attempt had a hold of the database without releasing it correctly when it ended.

Let me know if this continues to be an issue in future releases.

Jaksuhn commented 12 months ago

yeah I don't actually need it running on other instances, however I do not enable/disable collections every time I open other instances so whatever is on my main is on the alts. I suppose "simplest" would be to just have per character dbs, but I'll see how the lock release works some time this week when I can test it again