How do you get code to execute at the end of a procedure? - openedge

I'm working on a new piece of code at work to assist the rest of the programmers in making app server calls. Previously we just had a .i file and relied on the developer to make sure you made all the right calls and cleaned up the app server connection at the end of the program. Obviously some people have forgotten to do that in the past and it's caused problems for us.
I've been building a basic appserver.cls file, but I can't figure out how to get it to disconnect at the end of the program.
I've tried the following things so far.
ON CLOSE OF THIS-PROCEDURE
DO:
clAppServer:cleanupAppServer().
END.
This doesn't seem to fire at the end of the webspeed call.
DESTRUCTOR appserver():
cleanupAppServer().
END DESTRUCTOR.
This works when it does garbage collection, but Progress doesn't seem to do garbage collection at the end of a webspeed call and the objects are still in memory (which is an entirely different issue that I need to deal with).
ON CLOSE OF SESSION:LAST-PROCEDURE
DO:
clAppServer:cleanupAppServer().
END.
This doesn't even compile obviously.
I've tried a whole bunch of other things that are variants on these three to no avail.
Is there any way to do what I'm asking? Bonus points if it can be inside the appserver.cls file.

If I understand the question, you want to disconnect from another AppServer once the work is done. Would try something along the lines of the below work?
Create a AppServer-handle-wrapper class. This class is responsible for the A/S connection; it has a public "Handle" (or similarly-named) property that you can use to run stuff on the AppServer.
In this class' destructor you can add code that does your clean-up : disconnect and delete server handle .
Code that wants to run something on the AppServer does something like ...
def var asConn as AppServerConnection.
asConn = new AppServerConnection().
run foo.p on asConn:Handle (param1, out param2).
// cause GC
asConn = ?.
// manually destroy
delete object asConn.
The destructor will then do the right thing.
Note that if you have this code in an internal procedure or method, then the variable would go out of scope at the end of it, and the GC would kick in.
There's an example of this approach at https://github.com/consultingwerk/ADE-Sourcecode/blob/566ac0a6e085d6305a8f364f13a1d805d3597d2a/src/netlib/OpenEdge/Net/ServerConnection/ClientSocket.cls
Bear in mind that in the ClientSocket is that the handle is private - you may want to make it public for a general AppServer connection.

Related

'ChromiumWebBrowser' does not contain a definition for 'NewScreenshot'

I'm just looking into CefSharp and am confused about NewScreenshot. I've found lots of references to it as well as example code, but none of it works. I found it marked as obsolete in the 63.0 docs...
Has NewScreenshot been removed? If so, what replaces it (how can I tell that the screen has rendered)? For my purposes a blocking (non-async) method would work fine.
Update:
Searching the source for the latest version of CefSharp I find no reference to NewScreenshot.
I started with the Minimal Example that #amaitland referred to. I made a few changes, adapting it for my use. As part of that change I moved the Shutdown() call to the program's destructor.
When I ran the project I received a mystifying error about calling Shutdown() from a thread different than the thread from which Initialize() was called.
Looking through the code I saw ScreenshotAsync and, as I wasn't (knowingly) using another thread, suspected it may be involved. I looked for another way to get my SVG image and found NewScreenshot. Which of course didn't solve my problem, which was that the GC was running my destructor in a different thread (I had no idea that could happen).
At any rate, by this time I'd shucked ScreenshotAsync for NewScreenshot which is how I ended up here.
I set a breakpoint in my handler (which I haven't included as it's never called). Here's what I hope is the relevant code. I've omitted the init code but I believe it's unchanged from the example.
public static void Main()
{
private const string url = "https://www.google.com/";
browser = new ChromiumWebBrowser();
browser.Paint += OnBrowserPaint;
browser.Load(url)
Console.ReadKey();
}
In stepping through the code in the debugger, I set a breakpoint on browser.Load(url). If I examine browser.Paint, I find errors:
Here's the tooltip for DeclaringMethod:
I have no idea if this is related to my event handler not firing, but want to point it out in the event it is involved.
I appreciate your other suggestions but feel I need to find out why an event that should be firing is not.
I'll be happy to reduce and upload the project if it will help. Oh, and thanks for your help!

Spawn object with custom script with Unity Network

I have a PlayerPref that spawn more objects in OnStartLocalPlayer().
So in OnStartLocalPlayer() it call Command(assume that called on server) that instantiate GameObject and setup some values of its scripts. At the end it calls SpanWithClientAuthority()...
The thing is that on owner client and on server those script tweeks are correct, but on all other clients it lost all that settings(ex. gameobject ref etc). What do I do wrong?
Once more in nutshell: playerPref GO must have ref list of several other objects, and those objects must have ref to that playerPref GO. (making them part of playerPref GO is not a solution).
If I understand your problem correctly, you need the references to be set across all clients who have the same game object. [Command]'s are for client to server. What you need is a [ClientRpc]. Make the OnStartLocalPlayer() call a [ClientRpc] function, in that function (ex: RpcSetRefs()) set the references you need each client to have.

Asp.Net MVC double submit/request breaks SQL connection

I am running into a strange problem I don't fully understand. The main symptom is that when I double click a link (that points to a controller action) in my MVC application, my database server connection gets blown, and I get the error :
Execution of the command requires an open and available connection. The connection's current state is broken.
If I step through starting at a breakpoint at the top of the controller action, it will step down a couple lines and then jump back up to the breakpoint. Somehow the first request isn't executing fully before the second one gets there, and somehow my database connection breaks when it gets to any query. Every time this happens, I have to restart the application server.
It was happening intermittently at first, but the double clicking of links seems to reproduce it everytime. Does this happen to anyone else? What am I missing here?
Thanks,
rusty
Update :
A.) I incorrectly tagged this as Linq-to-sql when we are actually using Linq-to-entities.
B.) The connection object is defined as a member variable of the controller :
namespace C2S.Controllers
{
public class ArtifactController : Controller
{
private c2sEntities _entities = new c2sEntities();
...
I noticed in some of the asp.net tutorials they declare the variable in the same spot but have a separate constructor for the controller where the db object is initialized. Does this make any difference?
C.) The problem is not only with the double-clicking as described above. The connection breaks at other seemingly random times; I cannot seem to reproduce the error consistently (even double-clicking does not always break it). Restarting the web site usually fixes it, although sometimes I have to restart the host machine. After its back up, repeating the same sequence of actions usually does not reproduce the same error!
Maybe there's something I don't understand about setting up my linq-to-entities classes or the nature of the database connection. Does anyone have any thoughts? I really don't even know how to investigate this one!
Thanks again
Rusty
It's a bit difficult to say from your description of the problem, but a first guess would be:
Is your connection object static (i.e. controller or application level) or defined locally within the action? Double clicking a link would fire the event twice and that sounds like what you are describing here. So the first call creates the connection, then the 2nd call comes in and tramps all over the 1st call to the method, breaking the connection it thinks it has.
Edit: Does the problem only occur on double clicks. Does it work as expected if you only single click on the link? An example of the code in question would help.
I am guessing that you're not properly closing your database connection. You should consider making use of the using statement.
using(SqlConnection conn = new SqlConnection("connstring")) {
using (SqlCommand cmd = new SqlCommand("SQLSTATEMENT", conn)) {
// more code here......
}
}
This will ensure that your connection is closed even if there's an error in your code somewhere.
Read all about it here: http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx

create a queue of process in classic asp

here is the problem :
there is classic asp app which is calling lame.exe for encoding mp3s for lots of time per day
and there is no control of the way of calling lame.exe from several users in another word there is no queue for that purpose.
so here is what I am thinking about :
//below code all are pseudo-code
//process_flag and mp3 and processId all are reside in a database
function addQ(string mp3)
add a record to database
and set process_flag to undone
then goto checkQ
end function
function checkQ()
if there is a process in queue list and process_flag is undone
sort in by processID asc
for each processID
processQ(processID)
end for
end function
function ProcessQ(int processID)
run lame.exe with the help of wscript.exe
after doing the job set the process_flag to done
end function
so I just want to know is there any better solution?
or any other approaches out there?
regards.
Looks like a reasonable approach for classic asp.
Just make sure that in your checkQ function, you are only retrieving queue items that have the process_flag set to undone, or you might be trying to re-process the same items over and over.
Read this article for another approach using MSMQ - it starts by creating a new Public Queue, then sending messages to it from your asp page. It also required an additional executable to process queued items.
This is a perfect application for MSMQ. Let proven code handle the reliable messaging, concurrency control etc. so you can just focus on the application logic.

Flex: DeepCopy of FileReference

in my project, I let users pick pictures using the FileReference class. I then load these pictures into their .data properties, using the load() function. After this I perform some local manipulation and send them to the server.
What I would like to do, is to be able to iterate over the picked FileReferences again, load them into .data properties, perform different manipulation and send them to the server once again. I know that I should be able to do this from user-invoked event, that is not an issue here.
Problem is, once the FileReference is loaded for the first time, I can not unload it in any way, and I can not keep the data for all the pictures in the memory because these are huge.
So I guess there is only one thing I can do, which is performing a DeepCopy on the FileReference... Then I could load the first version, scrap it and use the copy for the second 'run'.
I tried to use ObjectUtil.copy, but when I access e.g. .name property of the copy, it fails with:
Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
at flash.net::FileReference/get name()
the relevant snippet:
registerClassAlias("FileReference",FileReference);
masterFileList.addItem(FileReference(ObjectUtil.copy(fr_load.fileList[i])));
trace(masterFileList[i].name)
Is it true that there are some protected properties of FileReference class that prevent it from being copied? If it is so, can I sidestep this somehow? Or is there any other solution to my overall problem?
I appreciate any hints/ideas!
I was trying to do almost exactly what you were doing, and I almost gave up after reading some of the answers, but I think I found a way to do it. I've found that if you have a FileReference object and call load() multiple times, it will work, but the main problem is that you're keeping the high-res bytes in memory after the first load. As you've mentioned, for people who don't know image processing, this is a big no-no.
The way to get around this is that after your first load(), you need to call the cancel() method on FileReference. From my testing so far, it looks like that will clear out the bytes in the FileReference, and load() will still work if you call it a second time later. Just a word of caution, this isn't explicitly-defined behavior in the API, so it is definitely subject to change, but it may help get you where you need to go in the mean time.
Hope that helps.
you cant use a ObjectUtil.copy. This method is designed for copying only data objects (VO classes).
you should create a new FileReference and copy the porperties, one by one. Create a function to do this..
Would copying it to a temporary file and then uploading the temporary file work? For example
var fileRef:FileReference = new FileReference();
fileRef.browse();
......................
var tmpFile:File = File.createTempFile();
try {
var tmpFileStream:FileStream = new FileStream();
tmpFileStream.open(tmpFile, FileMode.WRITE);
trace("Opened file: " + tmpFile.nativePath);
tmpFileStream.writeBytes(fileRef.data);
trace("copied file");
} catch ( error:Error ) {
trace("Unable to open file " + tmpFile.nativePath + "\n");
throw error;
}
I'm thinking that the operation is completely disallowed, for good reasons. If you can duplicate a new FileReference through ActionScript code, then you'd also be able to manufacture a FileReference object through ActionScript code. Of course, that'd be a pretty bad security hole if you could force the upload of an arbitrary file.
Keeping a copy of the data in memory really isn't that bad of a solution. After all, it's temporary. The typical client computer should be able to manage a few hundred extra MB of data with no problem. It's certainly a better option than having their browser do two separate uploads, which is what your attempted solution would end up doing.
A completely different potential solution to this problem is to avoid image manipulation by Flex altogether. Flex could post the uploaded file directly to the server, and the server could do the image manipulation itself. Of course, if the manipulation is driven through user interactions, then that wouldn't work at all.

Resources