I'm currently working on multithreading for one app. Ran into some issues so I'm trying bunch of different solutions. Is it possible to create a datastore object and then pass it to shared memory?
Currently I'm getting this error - Exception: Object passed to shared/remote object method is not a nonvisual user object.
Seems like only non visual objects are able to be passed?
First inside my initialize function, i test the length of the blob being passed. Then I setFullState on the datastore for the corresponding thread. Once that is done, I call getFullState on the datastore once more to grab its "new" blob. The old blob and the new blob should be the same every time, but sometimes they are not. For example the old blobs length is 32968 and sometimes the new one is 30476, but it should be 32968 every time. Finally I use GetSQLSelect() to see why the blobs aren't matching up and here I get random changes, like the string is blank or random characters. Another example where the old blobs lengths is 47662 and the new one is 34148, and getSQLSelect() prints a string thats just "G". These changes are random, and they don't happen every time so I'm not sure what to do.
My code inside initialize, the child threads.
ll_blob_length = Len(This.dataObjectBlob) //checks the len of the passed datastore blob
if this.l_connect_database() then // this.l_connect_database() used to connect to Oracle database
This.do_object = create datastore
if IsValid( This.do_object ) then
This.do_object.SetFullState(this.DataObjectBlob)
if This.do_object.SetTransObject( This.SQLC_Local ) = 1 then
Result = true
end if
end if
end if
blob newBlob
this.do_object.GetFullState(newBlob)
if len(newBlob) = ll_blob_length then
print(OK)
else
print(ThreadName + ": " + len(newBlob))
print(do_object.getSQLSelect())
1. In the main thread, just for testing purposes, do the SetFullState/GetFullState using a newly-created DataStore and see if the blob's length is the same. It should be... IF the assumption that it should be the same is correct. If not, is it the same each time you test using identical data?
2. Pass the blob's length along with the blob to the shared object thread.
3. In the shared object's thread. Test the blob argument's length to see if it matches the length argument's value before doing you load the blob into the DataStore. Again, it should match, if the assumption is correct.
4. See what happens with a more scaled-back test... say, two shared object threads instead of 24. If no problems arise with two threads, slowly increase to see if there is some (unknown) threshold being crossed. The available memory on any machine is not infinite. Only Appeon Engineering can determine if there is some undocumented practical limit to the number of threads that can be spun up.
Hope this helps. Good luck!
2. I tried passing the blobs length. Its the same length as the length i get when checking the blob inside the child thread.
3. Yes in my case it does match.
4. Seems like 6 is the sweet spot. This feels way too low for something as simple as this right? I reached out to Appeon Engineers about my issue last week with a slightly tweaked version of my app compared to what i'm asking on this thread. Still waiting on them to analyze my issue, which is why I started this thread in hopes of finding different solutions like passing a datastore to a shared object, and that led me to Rene's answer. I hope Appeon Engineers are able to analyze the issue successfully soon.
A "band-aid" solution i've come across for my issue is to manually set the SQL statements from a .txt file with .SetSQLSelect(). This has been the best temporary fix but I need to get to the bottom of the real problem since future apps I work on might come across this problem as well.
I'm trying to make sense of the error im getting. I noticed that when I put a Sleep(this.TreadIdent) before `This.do_object = create datastore` inside initialize() those errors seem to go away. So it sleeps for each thread, thread1 sleep(1), thread2 sleep(2)... thread24 sleep(24). But this isn't an optimal solution, the program has to wait 24 seconds for threads to get initialized. I tried making sleep smaller, for example this.ThreadIdent/2 so halving the total time to 12 seconds, however the errors come back but not as frequent. Now, i'm not sure how sleep() fixes this, but it seems like its some sort of timing and memory issue maybe?
I think i have exhausted all my options for a solution, I might have to just rely on my band-aid until Appeon reaches back out to me. But if you have any other suggestions or advice i'm open to them!
Thanks for all the help!