Hi Rick,
I've noticed since moving to 7.32 that the app update process appears to not automagically restart after the upload is complete. When I moved from 7.25 to 7.30 just last week it was fine. (Note: my app runs in COM mode.)
I've been using the same build PRG based on what WWC creates pretty much since day one of launching our app.
I'm testing this in my stage environment. I run the PRG which rebuilds the EXE, uploads the file and then makes the HTTP POST request to swap out the EXE and presumably properly restart when the first request comes in post-update. The update URL is:
https://<my staging site>/UpdateExe.wc
After pushing a new build I see this on the monitoring page:
I go to my staging home page and generate a request. I get:
I go to the admin page, flip over to File mode, manually load the servers, then flip back to COM mode and the app is now up and running normally.
I believe I have the all the DLLs properly updated: (wwDotNetBridge, wwIPStuff in my deploy folder; webconnectionmodule, wc in my web/bin folder). Maybe I'm missing something else? Please advise.
TIA

The app only restarts in COM if it gets hit. You won't see any instances if the app is idle.
+++ Rick ---
What happens if you manually reload?
+++ Rick ---
That's the issue. I have to manually reload. That screenshot of unable to retrieve is what I get after the build PRG does its thing. Prior to this release it would just work as you mentioned.
If you can manually reload, the servers should auto-load on demand. There's nothing magical that happens after an upload - it's just the same mechanism that's used when the app starts up for the first time.
Make sure you are in COM mode (do a clean GET request to make sure).
+++ Rick ---

"Should" being the operative word. 😃
I'm always open to the possibility of me doing something dumb but I've also been pushing updates like this for 3 years now. I've pushed several test updates to my stage environment and one to my production environment today. In each case I've had to manually restart the file instances before normal behavior resumes.
I just pushed another test update. I have not done anything else. The app is throwing the unable to retrieve server instance. I can get to the handler status page. All the admin page log options also say unable to retrieve a server instance.
Clicking Re-Read Configuration om the handler page does not help. Clicking Update Server Count does do the trick. That's a lot less clicking around then switching to file, loading servers and switching back to COM. Going to try this again and see if it's consistent.
Yep, the Update button next to the server count restores order to the universe. I've been holding off on another production update until I could get your advice but this will be fast enough for the moment. Having said that anything I can do or check that can help track this down please let me know.
I'm not following what you're doing.
You need both steps in order to update and replace. Unless you use the bld_MyApp.prg
which fires both of those commands successively and should do the full replacement. If you can do it manually (ie. Upload, then Replace) it should also work with the program which does the same thing. However, you need to watch and make sure you see the error or success page. If you get an error the update might have not
worked. However, if that's the case you then should just end up with the old application running because nothing got replaced.
The only way this can fail if there's a problem with the COM registration which could result in a new file but a broken COM registration. That's highly unlikely unless you don't have the right permissions and if that's the case you likely can't copy in the first place.
+++ Rick ---
I am not using the upload button on the admin page. I am using a bld program, somewhat modified for my environment.
************************************************************************
* Project Build routine
****************************************
*** Function: Builds EXE, configures DCOM and optionally uploads
***
*** Assume:
*** Pass: nothing to just create exe, .t. to upload to server, stage, prod, devrk to select location
*** Pass: added 3rd param to just upload EXE
*** Return:
************************************************************************
#INCLUDE rkdev.h
LPARAMETER m.llCopyToServer, m.tcDestination, m.tlUploadOnly
LOCAL lcFile
IF VARTYPE(m.tcDestination)<>[C]
m.tcDestination=[]
ENDIF
DO wwUtils
IF !IsAdmin()
MESSAGEBOX("Please run this command under an Administrator account, " + ;
"otherwise the project and COM object can't be registered. " +;
CRLF + CRLF +;
"Use 'Run As Administrator' to Start Visual FoxPro.",;
16,"Build Web Connection Project")
RETURN
ENDIF
*** Configure these options to perform tasks automatically
EXE_FILE = "Rfc3"
DCOM_ProgId = "Rfc3.Rfc3Server"
DCOM_UserId = ""
*** Server Update Urls - fix these to point at your production Server/Virtual
DO CASE
CASE m.tcDestination=[s]
HTTP_UPLOADURL = "https://<my stage env>/UploadExe.wc"
HTTP_UPDATEURL = "https://<my stage env>/UpdateExe.wc"
CASE m.tcDestination=[p]
HTTP_UPLOADURL = "https://<my prod env>/UploadExe.wc"
HTTP_UPDATEURL = "https://<my prod env>/UpdateExe.wc"
CASE m.tcDestination=[d]
HTTP_UPLOADURL = "https://<my dev env>/UploadExe.wc"
HTTP_UPDATEURL = "https://<my dev env>/UpdateExe.wc"
OTHERWISE
HTTP_UPLOADURL = "https://<my stage env>/UploadExe.wc"
HTTP_UPDATEURL = "https://<my stage env>/UpdateExe.wc"
ENDCASE
*** Optional - User name to pre-seed username dialog
WEB_USERNAME = StrExtract(sys(0),"# ","")
*** Make sure classes is in the path
DO PATH WITH ".\classes"
SET PROCEDURE TO
SET CLASSLIB TO
*!* - rk - 2021-7-14 - add param so i can avoid the overhead of building again when pushing to prod. assumes the normal workflow is stage then prod.
IF NOT m.tlUploadOnly && then we want to build the EXE
BUILD EXE (EXE_FILE) FROM (EXE_FILE) RECOMPILE
ENDIF
*** Released during build
DO wwHttp
IF FILE(EXE_FILE + ".err")
MODIFY COMMAND (EXE_FILE + ".err")
RETURN
ENDIF
*** Note: Local DCOM config so you can see your server
*** On remote we perform no DCOM configuration which is recommended
*!* - rk - 2021-7-14 - only call this if deploying locally
IF m.tcDestination=[d]
DO DCOMCnfgServer with DCOM_PROGID, DCOM_USERID
ENDIF
IF llCopyToServer
lcUserNameHttp = InputForm(PADR(WEB_USERNAME,15),"Http Username","Code Update")
IF EMPTY(lcUsernameHttp)
RETURN
ENDIF
lcPasswordHttp = GetPassword("Please enter your HTTP password")
IF EMPTY(lcPasswordHttp)
RETURN
ENDIF
WAIT WINDOW "Uploading file to server." + CRLF + ;
"This could take a bit..." NOWAIT NOCLEAR
loHttp = CREATEOBJECT("wwHttp")
IF !EMPTY(lcUsernameHttp)
loHttp.cUsername = lcUsernameHttp
loHttp.cPassword = lcPasswordHttp
ENDIF
loHttp.nHttpPostMode = 2
loHttp.lUseLargePostBuffer = .T.
loHttp.AddPostKey("File",FULLPATH(EXE_FILE + ".exe"),.T.)
lcHtml = loHttp.Post(HTTP_UPLOADURL)
IF (loHttp.nError != 0) OR ATC("File has been uploaded",lcHtml) = 0
MESSAGEBOX("Upload failed." + CRLF + ;
loHttp.cErrorMsg)
RETURN
ENDIF
WAIT WINDOW "File upload completed..." NOWAIT NOCLEAR
lcURL = InputForm(PADR(HTTP_UPDATEURL,100),"URL to update Exe","Update")
WAIT WINDOW NOWAIT "Updating Exe File on Web Server..." NOCLEAR
loHttp = CREATEOBJECT("wwHttp")
lcHTML = loHttp.HTTPGet(lcUrl,lcUserNameHttp, lcPasswordHttp)
WAIT CLEAR
IF !"Exe File Updated" $ lcHTML
ShowHTML(lchTML)
ELSE
MESSAGEBOX("Update completed",MB_OK+MB_ICONINFORMATION,"Web Connection Server Code Update")
ENDIF
ENDIF
BTW there's a small bug in the standard template for the text string that indicates success. The template has Exe Updated
but the response actually has Exe File Updated
.
I can't say I've done anything recently with the COM registration but maybe there's a clue there?
Don't know - check the update url - looks like that'll need trimming.
+++ Rick ---
I assume you're referring to the lcUrl
var that gets populated by the INPUTFORM
call. I'll slap an ALLTRIM around it and see if it makes any difference. (That bit of code is unchanged from the template BLD PRG.)
Yeah I see that the padding is being set to make sure the field is wide enough - I guess it's being trimmed.
I don't know what to tell you. Look at the HTTP command and what comes back and compare to what the manual steps do. Maybe there's a typo in the Urls.
+++ Rick ---
The lack of consistency here is very confusing.
As recommended, I stepped through the call to the update page (multiple times). Pushed a new build. Worked as expected. Got the standard success HTML, response 200. Pushed another build. The COM instances did not restart but the call returned a 200 and there were no other obvious (to me) errors. Did it several more times. Still no COM instances. Click the server count Update button. Back in business on the first request. Push another build. Instances stop, EXE swapped successfully as best I can tell, unable to retrieve instance on first request. Click the server count Update button. Back in business. Whatever happens in in the UpdateExe.wc page is not debuggable by me.
Both the bld_MyApp
and interactive Update EXE functionality should be identical. They have to be - they're using the same URL and are running exactly the same code.
That's why I say you need to step through the bld_myapp.prg
and see what the UpdateExe
call returns. Based on what you're saying it sounds like that request is failing.
If everything works you should see a confirmation page that shows the updated EXE, Size and Version:
(There may be formatting differences but the content should show)
If you don't see this page the update likely failed in which case you need to look at the wwHttp
call and see what it does return and what the URL is and whether the credentials are passed etc.
+++ Rick ---
I never use the interactive Update EXE thing so can't speak to it. I've been using a bld prg since the beginning of our WWC adventure (going on 3+ years now).
I did step though it; multiple times. Promise. 😃
You'll have to take my word that PW is properly populated. As you might notice I changed my bld prg from the default behavior to only bother rendering the response HTML when it was not successful in swapping the EXE. When it fails the response page makes it pretty clear that it failed.
Here's a screencap of the success page:
I go back to the home page of my app, click on the logo and get this:
Here's the handler status page (no COM instances appearing):
I suppose I can try the upload and swap buttons from the admin page and see if anything different happens? And again I swear this only started happening with 7.32...
So I did an update of my own site here and well... I saw the same thing.
I was able to upload, get a success page. Then if I did nothing else following requests give me Server Instance not available. Also happens with the interactive Udate Exe button.
Not sure what is happening there. Explicitly loading servers fixes it. So maybe adding an explicit call to:
https://yoursite.com/LoadComServers.wc
via wwHttp
does the trick.
Not sure what could cause this problem though and pretty sure nothing has changed in this code base that updates or loads servers.
I just tried the more manual method. I built the exe, used the Upload button (.net version), clicked the Swap button on the page I got after the upload completed, got this result.
But I still go this when I clicked the logo in my app:
The status page shows no instances:
Click the server count Update button and it's happy again. I wish I could provide more useful info...
Good to know that it's not just me... 😉
I'll try integrating that call into my bld PRG.
Would that be a GET or a POST? Using the bld code as a template, would it be something like this:
lcHtml = loHttp.Post(https://yoursite.com/LoadComServers.wc)
Ands then parse the response object for success/failure?
Or do I use a GET with the user/pw like the upload URL?
A little experimentation on my part says the GET with the creds is the way to go. But please disabuse me of that notion if this the wrong way to call the LoadServes page.
Thanks!
Oh man... I took a look and sure enough there was an innocent change made a couple of versions back that was causing a lookup to fail in the .NET Handler. Basically I reset a collection to a new collection rather than using null
and then used an invalid check value (the configured ServerCount
vs. the actual Servers.Count
). In a nutshell the auto-loading code never fired in that scenario. This worked fine for explicit loading (still used the old null
instance) but not for a few of the other admin handlers.
Long story short I've updated all those checks to properly use a Servers.Count
to determine whether instances need to load in addition to the null
check.
You can download an updated version from:
Web Connection Experimental Updates
- Unzip
- Install
WebConnectionModule.dll
into your projects.\web\bin
folder
+++ Rick ---
All changes are innocent... 😃
I wish to be memorialized in your source code comments as the discoverer of this issue. 😃
Thanks, Rick!
Not that you need the confirmation but I deployed the updated DLL and pushing updates now behaves properly again.
I wish to be memorialized in your source code comments as the discoverer of this issue.
For the low price of..... 😄
A fine question. I'll have my agent get back to you... 😉
Richard,
I will gratefully credit you for this timely discovery. We just got our first customer complaints about COM not auto-loading after deploying the updated dll. It was nice to find that the issue had already been hashed out with a fix ready for downloading.
--stein