-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Change Natlink to work out of process by default #198
Comments
In principle, I support this idea, as you know. I hope, that this will make the install and maintenance procedure more simple. Starting a python process after starting Dragon is a minor extra thing when it makes other things more simple and robust. OTOH, now the natlink subsystem is started with Dragon, and therefore integrated in the Dragon speech input cycle at the deepest possible place, and a supported way by Dragon. I hope this close connection is not made weaker with your proposed solution. I think this needs to be discussed further! |
Thanks, Quintijn. I am confident that it will make installation, usage and maintenance simpler and more robust.
I appreciate your caution here, but I don't believe the connection will be made weaker by my proposed solution. I've used Natlink and Dragon this way extensively. The connection is the same one used by the test code — Natlink's and Dragonfly's.
If it does break, I take responsibility for fixing or reverting my changes.
…On Sat, 06 Jul 2024 06:26:43 -0700 Quintijn Hoogenboom ***@***.***> wrote:
In principle, I support this idea, as you know. I hope, that this will make the install and maintenance procedure more simple. Starting a python process after starting Dragon is a minor extra thing when it makes other things more simple and robust.
OTOH, now the natlink subsystem is started with Dragon, and therefore integrated in the Dragon speech input cycle at the deepest possible place, and a supported way by Dragon.
I hope this close connection is not made weaker with your proposed solution. I think this needs to be discussed further!
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
This will solve a number issues that would be difficult or impossible fix.
At the end of the day, this makes Natlink more portable and robust for the end user. There's one downside with how things currently would be structured out of process. Natlink does not start with Dragon automatically. This is a desired feature by user's. On the process of making a GUI that can display command history, rules and so forth there might be another opportunity. My thought is this GUI could be running in the system tray when OS starts. When Dragon is launched, it could also be watching for that process and automatically start natlink. The tricky bit is making sure it starts late enough. That might be worthy of some discussion.. |
We agree on most of the above, I think. An autostart feature goes beyond what I had in mind here. As Quintijn said, it is a minor extra thing for the user to do. Maybe it can be considered further down the road? I am still in the planning phase on this. A polished GUI like that might be good as a setuptools "extra" for 'natlinkcore', to be installed alongside it. I can help you with the last part at least. Use the `natlink.isNatSpeakRunning()' function. |
Great, Dane, I did not think about the Eventually, you only need to start Natlink: if Natspeak is not running yet it is started from the script, with configurable user (in natlink.ini), wait for the load procedure of Natstpeak. After that, you can go ahead. |
Here's my attempt to change how PYD gets loaded.
It seems the PYD is loaded successful but something still not right as evidenced by the following tested through dragonfly.
See above after beginning of utterance grammar decode never happens above despite dragonfly showing an active rule! Below is with the Dragonfly text engine
It would be nice to get a simpler test just with natlink without dragonfly. I've sent through chat (It's too big to upload here) One thing I'm not sure is how the pathway of natlink c++ is initialized out of process. For example relevancy of appsupp.h |
alternative ways to get dragon out of process include DLL Surrigates https://learn.microsoft.com/en-us/windows/win32/com/using-the-system-supplied-surrogate. You can use the Running Object Table to host a singleton natlink object (or a bunch of COM objects as you desire) that can accessed by name. You can also host natlink in an NT Service if you really wanted to, so it is always available for natlink to connect to. I have no idea if any of the above are applicable or helpful to what you are working towards. |
Here's a quick easy way to test that have been successful on my system. The issue of recognizing commands during the Decode time at least in dragonfly is an issue. I have yet to test directly with natlink. Thank you @quintijn for simplifying this process! Download natlink_vert_out_of_process.zip link is valid for 30 days
Warning
Reverting to Natlink installer
Technically I'm not sure if it's even required to uninstall/deregister Natlink. However I have run into issues where the virtual Python tries to pick up on natlink site packages in C:\Program Files (x86)\natlink. For testing purposes use a clean system without Natlink. No need to uninstall system Python. Test Example
I will be codifying these into tests that can be executed by bat files running python scripts. If the culprit is figured out by closing processes I can create dedicated bat to forcibly clean the state. That way we can test figure out if anything specifically contributing to this bad state. I will make a new post with the new zip file when these tests are ready! Currently utilize what's above. |
I've tried registering pyd without my changes natlink init and leaving the Dragon ini vanilla. Dragonfly called through the cli with a demo grammar (Although I don't see decode in debug mode) are recognized, but not executed. The same, calling through natlink! |
I have not had a chance to test this yet, but these results do not sound encouraging. I suspect it is a problem with Dragon 16. I'll look into it and see what, if anything, can be done.
…On Sat, 13 Jul 2024 21:55:40 -0700 LexiconCode ***@***.***> wrote:
I've tried registering pyd without my changes natlink init and leaving the Dragon ini vanilla. Dragonfly called through the cli with a demo grammar dommands ( Although I don't see the decode debug mode) are recognized, but not executed. The same, calling through nalink!
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
natlink_vert_out_of_process_v2
|
The issue mentioned above — the broken recognition callback — appears to be Windows-related. I can reproduce it on Windows 10 with Dragon 15. It does not occur on Windows 7 with the same Dragon version.
The problem may be fixable. I have been able to determine that the callback is invoked, but causes a fault. I'll see if anything can be done about that.
I don't know about the dirty state issue. It does sound like what occurs when `natDisconnect()' isn't called.
|
Okay, good news. I managed to fix the broken callback. My proposal now looks viable on Windows 10. The same binary also works on Windows 7. Dragonfly's test suite now passes expectedly on both.
I did have to do some debugging and I can confirm it is easier this way. Simply attach Visual Studio's native debugger to your Python process and ensure the symbol file (natlink.pdb) is loaded.
|
@LexiconCode The dirty state issue that occurs if one closes Dragon before Natlink is solvable by waiting for the shutdown event and disconnecting cleanly. I have some code for this that works and will include it in my changes for review.
I assume you guys would like Natlink to remain open if Dragon is closed first and then reconnect when it can, rerunning the loader code. This seems intuitive to me.
|
Yes, that seems intuitive to me. Is it a simple, wait for dragen.exe to load then execute loader? |
Okay great. Yes, basically. There is a Windows event for DNS initialization that the program can wait for. |
I think it is ok to make the user launch natlink, or to launch it at startup, or when dragon restarts (which is not that often). |
I was thinking about this yesterday. I think I can retain Natlink's in-process mode and have the software merely work out-of-process by default. This would be a more modest proposal.
The in-process mode should be enableable via a post-install script for a single Python installation.
|
Any way the inprocess variant is kept as a possibility seems good to me. But I would like to have a stable natlink installer (inprocess) before we move on to installers that do out of process (by default). |
All right then. I do think 'pip install natlink natlinkcore' followed by a post-install script for inprocess would be simpler. But, I'll have a look into what can be done to stabilise the current installer. Maybe it could run those commands, or similar ones.
…On Fri, 30 Aug 2024 03:26:55 -0700 Quintijn Hoogenboom ***@***.***> wrote:
Any way the inprocess variant is kept as a possibility seems good to me. But I would like to have a stable natlink installer (inprocess) before we move on to installers that do out of process (by default).
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
This is somewhat tangential, but I think we should explicitly rule out supporting virtual environments in-process. That way, all the current |
There are no hacks needed for virtual environments in-process. All that is needed We should use |
I'm sorry, I just don't see the value of this. The function you refer to is not invoked by Natlink out of process. In that case it is invoked by the interpreter, python.exe. With my proposal implemented, one could use Natlink in a virtual environment out of process without needing administrative access rights or a signed installer.
As for in-process Natlink, the simplest way of using it is with a dedicated 32-bit installation, installed at the user or system level. This essentially already functions as an isolated environment, as I think it is fair to say most programmer users will do normal Python work with a 64-bit installation.
|
As to package pollution, the 64-bit Python programmer user who uses in-process Natlink could do their 64-bit work in a virtual environment. We could advise this in the docs.
|
I misspoke about PyConfig_InitIsolatedConfig for out of process. The virtual environment does solve other issues with how pip install packages through the installer. I'm not sure, but there might be another way around that issue. |
I now understand from our IM chat why you want this: in order to work around a separate problem, described in issues #178, #207, etc.
There's a term for this I learned only recently: the XY problem. It is where one tries to solve X in order to solve Y. I'll see if I can figure out what's causing Y here.
…On Tue, 03 Sep 2024 02:10:23 -0700 LexiconCode ***@***.***> wrote:
I misspoke about PyConfig_InitIsolatedConfig for out of process. The virtual environment does solve other issues with how pip install packages through the installer. I'm not sure, but there might be another way around that issue.
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
This proposal itself seems like an XY problem thing, too, now that I think about it. The problems with the installer, DLL registration, etc., are, I think, caused by Python 3 design changes and are solvable. Pywin32 is only a few years older than Natlink and has managed to solve similar problems.
Still, there are one or two possibly useful ideas to come out of this. I think it would be nice if Natlink's message window were to be controllable via a function similar to the setTrayIcon() function. What do you think, Quintijn?
…On Tue, 03 Sep 2024 02:10:23 -0700 LexiconCode ***@***.***> wrote:
I misspoke about PyConfig_InitIsolatedConfig for out of process. The virtual environment does solve other issues with how pip install packages through the installer. I'm not sure, but there might be another way around that issue.
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
Possibly the installer, inconsistent DLL registration, and some of the Python 3 package management could be solved. However in process requires editing dragon ini, and DLL registration. Fundamentally Natlink cannot be used in the multiuser system: On a shared system:
Other issues:
This is not a hypothetical environment. In my support of caster this is has kept Natlink from being used in university accessibility resource centers, corporate and home environments where multiple rely on Dragon with shared/multiuser environment. Out of process allows install without admin privileges. This greatly simplifies the user experience anywhere including the home environment. I haven't brought this up in the past because out of process had some outstanding issues which now are being addressed. The out of process solution fixes easily all of these issues. Most of us seem to be on board with out a process as the default moving forward. What is a technical reasoning for not following through with out of process as the default method? |
Maybe this will help:
from https://learn.microsoft.com/en-us/windows/win32/sysinfo/hkey-classes-root-key |
'IT departments have denied admin privileges to install Natlink which is often decided on a case-to-case basis.' I don't even think we should try to address that. If an IT department wants to support people who want or need to use dragon for their work, accessibility needs, etc, with natlink they can make that call. Let their stakeholders lobby them. |
As someone that is worked with many many people on this issue specifically I strongly disagree with this stance. We should be lowering the barriers for people when we have the ability to do so. |
As a concession we could do both in and out of process. If the following features were implemented for out of to process:
The installer could do in process and other methods could handle out of process. |
Thank you for writing this up, Aaron! I had not given enough thought to the multiuser scenario. You are quite right, Natlink's in-process mode would unusable on a multiuser system at the moment.
If Python 3, Natlink and any dependency packages were installed at the system level and if the Natlink DNS compatibility module did basically nothing unless enabled for the current user, perhaps through an HKCU registry key or the natlink.ini file, then it could work.
Having the message window controllable as I touched on above would make it easier for the in-process mode to do basically nothing for users who haven't enabled it. This change would also let us explore the out of process solution more gradually, if natlink is also put up as a package on PyPI.
I agree, mostly, with Aaron's points on IT departments and his above concessional feature list. Signing the installer (#87) would help with the IT department issue. Having out of process natlink start with Dragon could be done, but seems unnecessary. But again, we can look into that more gradually.
One unmentioned technical reason for not following through with this proposal is the growing complexity of my project plan for it. The plan is nearing the edge of intellectual manageability for me, has taken months and is still not finished. Natlink is an old, complex piece of software and I don't think we have another expert really capable of reviewing my changes to it. I don't want to cause headaches down the line.
The installer is easier to fix. The Python code already exists in the historical natlink configuration functions to modify the ini file and registry keys appropriately and to register the DLL. There are a few other things, but they're manageable.
…On Wed, 25 Sep 2024 17:24:08 -0700 LexiconCode ***@***.***> wrote:
Alternatively having both in and out of process. if the following features were implemented for out of to process:
- Having natlink start with Dragon out of to process.
- Releasing natlink as a pip package
- signing .pyd / installer
The installer could do in process and other methods could handle out of process.
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
This is where I'm a little confused, I think DNS throws an error on startup with just the compatibility module edited ini. Try the following:
I may be wrong but that's completely out of our control, right? I feel like I've missed something that conversation here. sorry!
I can understand that, thank you for your help! We all have our limits both in time and energy. |
You haven't missed anything, I hadn't thought of it! That error message box does seem to be completely out of our control. However, it is always indicative of a setup error.
It seems to me that this raises a solid argument for only supporting system-level installation:
1) Natlink's userbase includes users of multi-user systems.
2) Natlink's in-process server DLL and its dependency DLLs, including Python3X.dll, must be installed in globally accessible locations in order to prevent this error from occurring for other Dragon users on a multi-user system.
3) Software installed for all users covers the single-user system use case.
4) Therefore, Natlink and the Python 3 installation it uses should always be installed at the system-level for all users.
Again, Python 3 appears to be the real problem here. Its per-user installation default is incompatible with Natlink's in-process mode and should not be supported in this way by the project.
Thank you for your understanding and kind words! I think, given all of the above, a first-class out-of-process mode would still be useful, perhaps as a mode targeted more toward the programmer section of Natlink's userbase and downstream projects.
I'll try to put together a list of the minimal changes necessary to allow gradual, collaborative exploration and development of a new out-of-process user mode. Fixing the installer should be our priority for the moment, however.
…On Thu, 26 Sep 2024 17:47:08 -0700 LexiconCode ***@***.***> wrote:
> Natlink DNS compatibility module did basically nothing unless enabled for the current user, perhaps through an HKCU registry key or the natlink.ini file, then it could work.
This is where I'm a little confused, I think DNS throws an error on startup with just the compatibility module edited ini. Try the following:
1. uninstall natlink,
2. edit manually file as admin
3. started Dragon
4. error looking for compatibility module
I may be wrong but that's completely out of our control, right?
> One unmentioned technical reason for not following through with this proposal is the growing complexity of my project plan for it. The plan is nearing the edge of intellectual manageability for me, has taken months and is still not finished. Natlink is an old, complex piece of software and I don't think we have another expert really capable of reviewing my changes to it. I don't want to cause headaches down the line.
I can understand that, thank you for your help! We all have our limits both in time and energy.
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
I would like to add that my proposal from last year to use CPython's limited API (#171) would help us with both modes. It would take the pickiness about minor Python 3 versions away from the library and give it to the user as a freedom without us having to distribute more than one compiled installer/binary.
A minimum minor version requirement would still be enforced, of course. Obviously one is needed.
…On Thu, 26 Sep 2024 17:47:08 -0700 LexiconCode ***@***.***> wrote:
> Natlink DNS compatibility module did basically nothing unless enabled for the current user, perhaps through an HKCU registry key or the natlink.ini file, then it could work.
This is where I'm a little confused, I think DNS throws an error on startup with just the compatibility module edited ini. Try the following:
1. uninstall natlink,
2. edit manually file as admin
3. started Dragon
4. error looking for compatibility module
I may be wrong but that's completely out of our control, right?
> One unmentioned technical reason for not following through with this proposal is the growing complexity of my project plan for it. The plan is nearing the edge of intellectual manageability for me, has taken months and is still not finished. Natlink is an old, complex piece of software and I don't think we have another expert really capable of reviewing my changes to it. I don't want to cause headaches down the line.
I can understand that, thank you for your help! We all have our limits both in time and energy.
--
Reply to this email directly or view it on GitHub:
#198 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
All right sounds like we have pathway forward! |
As discussed over e-mail and in the developer chat, changing Natlink to work exclusively in normal Python processes would resolve a number of open issues and simplify the software (natlink and natlinkcore) significantly.
The text was updated successfully, but these errors were encountered: