I have a pretty complicated document modification logic. The problem raises when during this logic execution this document is modified by other caller. So when I call DocumentSession.SaveChanges I can loose some changes that were done by other caller. As a way to resolve it I implemented a patching script. My question is whether RavenDb guarantees the document will not be modified by other callers while patching script is being executed or not. So is there something like document modification queue in RavenDb internally?
Idsa,
You can resolve that without patching by setting UseOptimisticConcurrency=true; on the session, which will cause a ConcurrencyException to be thrown.
With Patching, we'll make sure that the patch is always running on a consistent view of the document, and it will only be applied if there has been no modifications. If there were modifications midway, the patch will be re-applied on the new version.
Related
I'm reading the NPM docs about package-lock.json and my interpretation is that a committed change to it can never cause issues in the deployed version.
During the roll-out we run npm install which creates (or overwrites) the lock file anyway. In my mind, the lock file is more of a receipt of the state of the concurrent world while installing, rather than a pointer on how the installation should be performed.
However, I haven't been successful convincing my team that it is so. They feel uneasy relying on the statement above (not contradicting it nor arguing against it, just not entirely convinced to the degree that they would bet a testicle on it).
Is it at all possible that package-lock.json might affect the actual installation?
Since I'm new with the company, my track record of 10+ years has limited impact. And I'm myself humbly considering that even though the lock file never caused me any issues before, my experience might be irrelevant if the local environment is configured in a way I'm not familiar with yet. So I'm too cautious to bet my reputation as we're about to make a very important release.
In my mind, the lock file is more of a receipt of the state of the concurrent world while installing, rather than a pointer on how the installation should be performed.
Maybe I am interpreting your statement wrong but package-lock is a pointer for future installations in a way. See the general documentaion on lock files (different link than the one you shared), following statement from the above doc might be helpful:
This file describes an exact, and more importantly reproducible node_modules tree. Once it’s present, any future installation will base its work off this file, instead of recalculating dependency versions off package.json.`
A read on following discussion on this topic might be helpful to you too. Thanks!
I have a product.msi having some custom action and it has been released.
patch.msp is a patch I made for product.msi.
when I remove this patch from Control panel => Add/Remove Program, custom action which in old package always run. that is not my expectation.
I don't want to run custom action when patch uninstall.
I also googled, but no good way fro released product, I can't change the wxs file to add condition for custom action.
Anyone can help me?
Most thanks your help!
A patch features patch-specific properties such as PATCH and MSIPATCHREMOVE. Use these conditions on custom actions to make them run or not run during a patch depending on what is necessary.
Be careful with the conditions on custom actions, they are complicated to get right. Here is a "MSI Conditions Cheat Sheet" to help you. I have not tested these conditions - testing is the only guarantee.
I am throwing in some further patching advice since this is difficult stuff to deal with. Please do read to save yourself trouble. Hate sending people down the wrong track with such a problematic technology:
If there are errors in a product's uninstall sequence your fix involves creating a very carefully designed minor upgrade that you can deliver as a patch. This is one of the best uses of a patch.
A minor upgrade does not uninstall the existing installation, but rater re-caches a new MSI file to use for maintenance and uninstall operations. Hence you can fix the uninstall before it is run.
Create a minor upgrade, test it fully as a regular upgrade install, and then package it as a patch. A patch is merely a distribution / delivery mechanism for an upgrade that works.
Don't waste time making a patch before the upgrade is verified. This is a common mistake that wastes a lot of time. In fact if the minor upgrade works, a patch may not be necessary at all. Just use the minor upgrade unless your MSI file is enormously big and you want to deliver a small "hotfix".
If you need to include files in your patch, I recommend enabling "include whole files". Otherwise bit-level patching is done, and this is unnecessary complexity (unless your binaries are enormous).
Include only what you need in a patch. Add no files or settings that are not required, and you can make a reliable patch. Avoid adding custom actions if at all possible.
Be aware that a patch uses the same InstallExecuteSequence as a regular install, but you can condition custom actions differently with patch-specific properties such as PATCH and MSIPATCHREMOVE. Use these conditions on custom actions to make them run or not run during a patch depending on what is necessary.
This "fix uninstall approach" is one of very few scenarios where I find MSI-patching can be successfully used. Otherwise patching is very complicated and error prone. It is also effective for small "hotfixes" to huge products - which obviously is what the whole technology is designed for.
Check Stefan Kruger's installsite.org for more upgrades and patching tips.
Check out this well known wix tutorial for upgrades and patches. And MSDN.
I created an installer, deployed to our test environment and got an error due to a missing dll (it was not included in the wsx file). Is it possible to create a MSP patch to ship the missing dll or is it better to simply create a whole new installer?
I tried following various examples but I keep getting this error:
DEBUG: Error 2356: Couldn't locate cabinet in stream: media1.cab.
A patch can do anything an updated MSI can do, but it is merely a packaging and delivery mechanism that delivers an update in a more compact way. Hence you must actually create a full new version of your setup to be able to then package this new update as a patch.
Important: spend no time at all testing a patch before the full upgrade is working properly. This is a complete waste of time. It creates only mysterious errors and is a very common real-world time drain.
Unless your previous setup has gone to production and hence is "out in the wild", I wouldn't waste my time with a patch. Patches require a lot of time to create and even more time to test - there is a lot of added risk and complexity, and it is only intended to be a convenient way to deliver small updates such as what you describe without having to distribute a potentially huge, new MSI file. It is not common to use patches for UAT or QA testing unless your product is really huge and takes ages to install.
Personally I feel that MSI has failed entirely when it comes to patching. It should be an easy to use, value added feature, but it has become a hugely complicated, problematic issue in its own right.
Yes, you can add a missing file through a patch. Perhaps this article will help: http://wix.sourceforge.net/manual-wix2/patch_building.htm
When creating a patch you should always modify your existing installer. You don't create a new installer from scratch. Also, never remove resources from the new version. For a patch you should either modify or add resources.
Regarding error 2356, it seems like the original installation is somehow corrupted. You can try repairing the old version before applying the patch on it.
I've noticed that whenever I have package-level constants (or any variables for that matter), whenever I recompile the package, persistent connections to the database get an error that "existing state of package body has been invalidated".
Is there a way to avoid this? Perhaps through synonyms? What are best-practices in this case?
In general, you should avoid replacing code in a live production instance.
If you really really have to be live 24/24 7/7, and you can't schedule ANY (even tiny) downtime you will have to avoid package-level variables since recompilation of a such a package will trigger the aforementionned error.
You could also catch the error in your client application and decide what to do. Maybe you have sufficient information to restart whatever the client was doing.
See also
This thread on AskTom covers the same topic.
The problem is if, at 10:00am, a session starts and the constant is set to 'A', then at 11:00am you change it to 'B', then the session 'blows up' in confusion.
The Serially_Reusable pragma may work for you. Basically it won't preserve state between calls. So at 11:0am it will just start using 'B'. If you can be 100% sure that won't break your code, it can work. Re-initializing the constants whenever they are needed may be an overhead.
Also look at calling DBMS_SESSION.MODIFY_PACKAGE_STATE or DBMS_SESSION.RESET_PACKAGE at appropriate intervals. That may reduce the number of errors you get.
You should also look at Edition-based redefinition in the new 11gR2. That's a more comprehensive solution, but I guess you'd need to upgrade for that.
In the past I've gotten around this by moving all state-related stuff into separate packages.
For example, if I had a package "CUSTOMER_PKG", I'd move all the global variables into a spec-only package called "CUSTOMER_GLOBALS_PKG".
Unfortunately this means exposing all private globals that were defined in the package body. We had to enforce a development standard so that CUSTOMER_GLOBALS_PKG was only allowed to be referred to by CUSTOMER_PKG.
I have an old VW3/ENVY image with a parcel loaded as unmanaged code (exactly the situation Mastering ENVY/DEVELOPER warns against). Unfortunately, this problem happened a long time ago and it's too late to just "go back" to an image without the parcel loaded.
Apparently, there is a way to solve this problem (we have one development image where this has been solved, and there are normal configuration maps that contain the exact same code as the unmanaged parcel but they can't be loaded), but the exact way has long since been forgotten (and there are some problems with taking that particular dev image as the base for a new runtime image, so I need to find out how how to do it again).
In theory, it should be possible to remove the parcel and reload the code from a configuration map. In practice, all normal ways (using the ParcelBrowser or directly calling UnmanagedCode>>remove) fail. I even tried manually removing the offending selectors from the method dictionary, but past a certain point (involving a call to #primBecome:) the whole image hangs completely (I can't even drop into the debugger). I started hacking the instances of the classes and methods, hoping I'd trick ENVY into thinking that these particular methods are normal versioned code, but without any success yet.
Are there any smalltalk/envy gurus around that still remember enough of VW 3 to provide me with any pointers?
Status update
After a week of trying to solve the problem I finally made it, at least partially, so in case anyone's interested...
First, I had to fix file pointers for the umnanaged code (otherwise, all everything that tried to touch the methods would throw an exception). It looks like ENVY extends Parcel so that, in theory, all integer file pointers are changed to ENVY's void filepointer when loaded, but in my case, I had to do it manually (a Parcel provides enumeration for all selectors it defines). Another way would be to tweak the filePointer code, but that can't easily be done automatically on every image where it's needed.
Then, the parcel can be discarded, which drops the parcel information, but keeps the code. The official "Discard" mechanism needs to have a valid changes file (which envy doesn't use so it has to be set manually, and reset afterwards) and the parcel source (which we fortunately had).
To be able to make any changes to the methods (either manually, or via loading an application or class from ENVY), they need to get rid of their unmanaged status. This can be done by manually tweaking TheClass>>applicationAssocs (I also got rid of all references to the classes in UnmanagedCode sich as timestamps, and removed the reference to the discarded parcel). I actually had some info on how to get to this point from my boss, but I haven't been able to understand the instructions until I almost figured it out by myself.
This finally allowed me to load and reload all the Applications that contained the classes. In theory. In practice, the image still hung completely whenever I tried to load a newer version of the Application (that contained the code formerly in the parcel).
It turned out that the crashes had absolutely nothing to do with the code being unmanaged, but with the fact that the parcel in question modified InputState>>process:, where it caused an exception due to a missing and/or uninitialized class variable (the InputState>>initialize method wasn't called until after the new process: method was in place). I had to modify the Notifier class to dump all exceptions to a file to find out what was going on. Adding the class variable to the source of the class (instead of adding it via reflection), suspending the input processing thread via toBeLoadedCode and starting it again in the loaded method and creating a new version of the application solved even this problem.
Now everything works, in theory. In practice it's still unusable, because reloading the WindowSystem or VisualworksBase applications causes their initialization blocks to run, and a whole lot of settings are reset to their defaults - fonts and font sizes, window colors, UI settings... And there doesn't seem to be any way to just save the settings to a file and load them later on, or just to see what all the settings are (either the official Settings menu doesn't show everything, or we have a heavily tweaked image... so much for reconstructing it from scratch). But that's a completely different question.
Well, normally the recommendation would be that you should be able to rebuild your development image from scratch by loading your code from the repository. But if you had that, then the answer would be simple, just discard that image and reload. I think it's been long enough that I've lost whatever knowledge I've had about how to mess with the internal structures to get it back, and it sounds like you've tried a lot of things. So, although it might be painful, figuring out the recipe to rebuild your development image by loading stuff from the repository sounds like it may be your best bet. It probably isn't all that horrible, there just might be a few dependencies on the image state, or special doits that need to be executed.
You also probably need to validate what's in the repository against what's in the image you're working from. If there was unmanaged code loaded and then someone modified it and saved it, it's not clear to me that it would have been saved to ENVY. So you probably want to audit everything that was unmanaged code and if it's been changed, save that to a repository edition.
Sorry I don't have any better answers.