mongoDB cursor timeout in C++ - c++

I get the following error using mongoDB through its C++ API on a 64-bit installation:
getMore: cursor didn't exist on server, possible restart or timeout?
The code snippet where the error is located is the following:
std::auto_ptr<mongo::DBClientCursor> cursor =
connection.query("database.collection", mongo::BSONObj());
while (cursor->more()) {
// Do stuff
// Update contents of fields
connection.update(...);
}
What the code simply does is updating the contents of each document's fields based on a specific data structure.
The code has been tested with a small data set, and it works perfectly fine, so I assume this is not a coding error, but rather a database-side error that is related to the size of the final data set.
My error looks similar to this bug report. The solution that is proposed there is to set the cursor to have no timeout, but there is no such function for the C++ API, although it seems to exist for other languages.
Any suggestions would be much appreciated.

Related

MFC CRecordset: Cannot flush newly added recordset to data source then continue updating it

I am working on refactoring some data-handling code in a MFC application that uses the CRecordset API (actually, a derived class from it, but the failures are coming out of CRecordset itself AFAICT) to talk to an ODBC data source backed by an Oracle database, but have encountered a sequence of operations that the CRecordset API, at least as of the version shipped with Visual Studio 2012 (which I know is old, but am hog-tied to for the time being) seems to be unable to perform.
In particular, in the following sequence of events, intended to flush changes to the record to the DB so that other queries performed during this sequence can see them:
CRecordset aRecordset(myDatabase);
aRecordset.Open(CRecordset::snapshot, "<some query that yields no records>"); // using CRecordset::dynaset doesn't change things
aRecordset.AddNew();
// set some values on aRecordset...
aRecordset.Update();
aRecordset.Requery(); // removing the Requery calls changes the failure mode
aRecordset.Edit(); // This call fails if the Requery is present
// perform query that needs to pick up on the values set on aRecordset above
// set some more values on aRecordset...
aRecordset.Update(); // This call fails if the Requery is not present
aRecordset.Requery();
aRecordset.Edit();
// perform query that needs to pick up on the values set on aRecordset above
// set yet more values on aRecordset...
aRecordset.Update();
aRecordset.Close();
I get two different failure modes, depending on whether the Requery calls are present or not.
With the Requery calls present, I get the following error from the first call to Edit in the sequence:
Error: Edit attempt failed - not on a record.
Operation failed, no current record.
while with them absent, I get a different error, this time from the second call to Update in the sequence, as follows:
Error: failure updating record.
Invalid cursor state
State:24000,Native:0,Origin:[Microsoft][ODBC Driver Manager]
Am I completely off my rocker in expecting CRecordset to be capable of flushing a newly added record to the database then going back to update the row further? Or is this a simple case of API operator error, and if so, what am I missing here? Is my Visual Studio/MFC too old for this fancy footwork?
Furthermore, it turns out that doing a .Requery() is not an option due to a requirement that I be able to .Open() a recordset with multiple rows, then do an .Edit()/.Update()/.Edit()/.Update() sequence on each row. Using the .Requery() in this case causes the cursor to be reset to the beginning with no good way to restore the cursor position, as the Oracle ODBC drivers do not support bookmarking across a requery.

Selenium Python Script, InvalidElementStateException

So I'm getting this error every so often when running the exact same test.
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=69.0.3497.100)
(Driver info: chromedriver=2.41.578706 (5f725d1b4f0a4acbf5259df887244095596231db),platform=Mac OS X 10.12.6 x86_64)
The only problem is that it seems to happen inconsistently to different areas of the code. It's when trying to access DOM elements, like a search field, of my ReactJS page. I'm running this through ROBOT Automation Framework, using a mix of the SeleniumLibrary and a custom library.
I've read that it's simply as it sounds, the xPath as become outdated on the DOM, but that doesn't help me figure out why it's an inconsistent error happening almost anywhere at any point.
EDIT: It seems to be happening in this:
def filter_modality(self, filter):
filter_value = '//span[#title="{}"]//parent::li'.format(filter)
self.selib.click_element(filter_locator)
self.selib.wait_until_page_contains_element('//*[#class="multi-selector-options open"]')
self.selib.wait_until_element_is_visible(filter_value)
self.selib.click_element(filter_value )
self.selib.wait_until_page_contains_element('//div...[#class="option selector-item active"]',
error=("Could not select filter: {}".format(filter_value )))
#I get the stale element message from or after executing this click_element
self.selib.click_element(filter_locator)
self.selib.wait_until_page_does_not_contain_element('//*[#class="multi-selector-options open"]',
error="Filter dropdown did not disappear after selection")
The exception comes when SE has found an element, but shortly afterwards something (a JS function) has changed it - removed from/rearranged it in the DOM, or changed its attributes significantly, so it's no longer tracked as the same element.
This comes for the fact that SE builds an internal cache of the DOM, which may become desynchronized from the actual one; thus the name "stale" - the el. is cached in some state, but its actual form is now different.
The issue is that common, that there is a specific SO tag for it - https://stackoverflow.com/questions/tagged/staleelementreferenceexception (I myself was surprised from this).
The common solutions are:
sleep for some seconds before an event you know will cause the issue
re-get an element before its usage (if you store a reference to it in a WebElement object, not really the case with robotframework)
have a rertry mechanism on working with an element that you know may cause the execution
swallow the exception and move along (I've done it in a few places, where the element was just a confirmation an operation was executed - it has been shown/found by SE once, afterwards I don't care is it changed in the DOM)

DCMTK Understand the "DIMSE No valid Presentation Context ID" error

I'm currently developing a simple application for querying/retrieving data on a PACS. I use DCMTK for this purpose, and a DCM4CHEE PACS as test server.
My goal is to implement simple C-FIND queries, and a C-MOVE retrieving system (coupled with a custom SCP to actually download the data).
To do so, I've created a CustomSCU class, that inherits the DCMTK DcmSCU class.
I first implemented a C-ECHO message, that worked great.
Then, I tried to implement C-FIND requesting, but I got the error "DIMSE No valid Presentation Context ID" (more on that in the next paragraph) from my application, but no other log from DCM4CHEE. I've then used the command tool findscu (from dcmtk) to see if there was some configuration issue but the tool just worked fine. So in order to implement my C-FIND request, I've read the source of findscu (here) and adapted it in my code (meaning that i'm not using DcmSCU::sendCFindRequest but the class DcmFindSU).
But now, i'm facing the same problem with C-MOVE request. My code is pretty straight-forward :
//transfer syntaxes
OFList<OFString> ts;
ts.push_back(UID_LittleEndianExplicitTransferSyntax);
ts.push_back(UID_BigEndianExplicitTransferSyntax);
ts.push_back(UID_LittleEndianImplicitTransferSyntax);
//sop class
OFString pc = UID_MOVEPatientRootQueryRetrieveInformationModel;
addPresentationContext(pc, ts);
DcmDataset query;
query.putAndInsertOFStringArray(DCM_QueryRetrieveLevel, "PATIENT");
query.putAndInsertOFStringArray(DCM_PatientID, <ThePatientId>);
OFCondition condition = sendMOVERequest(findPresentationContextID(pc, ""), getAETitle(), &query, nullptr);
return condition.good();
I've also tried using UID_MOVEStudyRootQueryRetrieveInformationModel instead of UID_MOVEPatientRootQueryRetrieveInformationModel, with the same result : my application shows the error
DIMSE No valid Presentation Context ID
As I understand, a presentation context is concatenation of one or more transfer syntax and one SOP class. I read that the problem could come from the PACS that won't accept my presentation contexts. To be sure, I used the movescu tool (from DCMTK). It worked, and I saw this in the logs from de server DCM4CHEE :
received AAssociatedRQ
pc-1 : as=<numbers>/Patient Root Q/R InfoModel = FIND
ts=<numbers>/Explicit VR Little Endian
ts=<numbers>/Explicit VR Big Endian
ts=<numbers>/Implicit VR Little Endian
That means that the movescu tool does a find before attempting an actual move ?
Therefore, I changed my application context creation with :
OFList<OFString> ts;
ts.push_back(UID_LittleEndianExplicitTransferSyntax);
ts.push_back(UID_BigEndianExplicitTransferSyntax);
ts.push_back(UID_LittleEndianImplicitTransferSyntax);
OFString pc1 = UID_FINDPatientRootQueryRetrieveInformationModel;
OFString pc = UID_MOVEPatientRootQueryRetrieveInformationModel;
addPresentationContext(pc1, ts);
addPresentationContext(pc, ts);
(also tried study root)
But this didn't do the trick.
The problem seems to lie on the client side, as findPresentationContextID(pc, ""); alwasy return 0, no matter what.
I don't feel like it's possible to adapt the code of the movescu tool, as it appears to be very complex and not adequat for simple retrieve operations.
I don't know what to try. I hope someone can help me understand what's going on. That's the last part of my application, as the storage SCP already works.
Regards
It looks like you are not negotiating the association with the PACS.
After adding the presentation contexts and before sending any command, the SCU must connect to the PACS and negotiate the PresentationContexts with DcmSCU::initNetwork and then DcmSCU::negotiateAssociation.

C++ Poco ODBC Transactions - AutoCommit mode

I am currently attempting to use transactions in my C++ app, but I have a problem with the ODBC's auto commit mode.
I am using the POCO libaries to create a connection to a PostgreSQL database on the same machine. Currently, I can send data to this database as single statements, but I cannot get my head around how to use Poco's transaction libraries to be able to send this data more quickly.
As I have several thousand records to insert, and so continuing to use single insert statements is extrememly slow and inpractical - So I am trying to use Poco's transaction to speed this up a bit (a fair bit).
The error I am encountering is a theoretically a simple one - Poco is throwing the following error:
'Invalid access: Session is in auto commit mode.'
I understand, as a result of this, I should somehow set "auto commit" to false - as it only allows me to commit data to the database line by line, rather than as a single transaction.
The problem is how I set this.
Currently, I have a session created from Session.h, that looks alot like this:
session = new Poco::Data::Session(
"ODBC",
connection_data.str()
);
Where connection data is a simple stringstream with the login information, password, database, server and "Driver={PostgreSQL ANSI};" to tell ODBC to utilize PostgreSQL's driver.
I have tried just setting a property "autocommit" to false through the session's setFeature or setProperty settings, this, of course, was to no avail. (it was more of a ditch attempt at this point).
session->setFeature("AUTOCOMMIT", false);
Looking around, I saw a possible alternative method by creating a ODBC sessionImpl directly from ODBC/session/SessionImpl.h instead of using this generic method above, and then creating a new session object from this.
The benefits of this are that ODBC's sessionImpl has references to autocommit mode in the header, which would suggest it would be able to handle this:
void autoCommit(const std::string&, bool val);
/// Sets autocommit property for the session.
However, having not used sessionImpl before, I cannot garuntee if this will work or if can can get this to work with the limited documentation available.
I am using C++ 03 (Not 11), with Visual Studio 2015
Poco 1.7.5
Boost (Where needed)
Would any one know the correct way of setting this feature (above) or a alternative method to achieving this?
edit: Looking at the source of poco, at:
https://github.com/pocoproject/poco/blob/develop/Data/ODBC/src/SessionImpl.cpp#L153
The property seems be named autoCommit, and looking at
https://github.com/pocoproject/poco/blob/develop/Data/include/Poco/Data/AbstractSessionImpl.h#L120
the case of the property names seem to matter. So, does it help if you use session->setFeature("autoCommit", false);?
Cant you just call session->begin(); and session->end(); on the corresponding Session object?
What is returned by session->canTransact()?
According to the doc begin() will start a new transaction, the doc does not mention any property that needs to be set before or after.
See: https://pocoproject.org/docs/Poco.Data.Session.html
Also faced a similar issue.
First of all before begin() need:
m_ses.setFeature("autoCommit", false);
m_ses.begin();
And the second issue is that this feature stays "autoCommit" in false for all other sessions. So don't forget for the next session call
session.setFeature("autoCommit", true);

Accessing Firefox tab element in nsIWebProgressListener::OnStateChange using C++

I am developing extension for Firefox 3.0-3.5 versions using VS2008.
I want to set attribute to a tab once the document load request completes within that tab window.
So in OnStateChange method, I am checking for document load.
I have used STATE_STOP & STATE_IS_DOCUMENT for it.
I want to determine which tab window has been associated with particular document request.
I have valid DOM Document pointer got from nsIWebProgress *aWebProgress which is 1st input
parameter of OnStateChange.
if ((aStateFlags & STATE_STOP) && (aStateFlags & STATE_IS_DOCUMENT))
{
nsCOMPtr<nsIDOMWindow> domwin;
nsCOMPtr<nsIDOMDocument> domDoc;
aWebProgress->GetDOMWindow(getter_AddRefs(domwin));
domwin->GetDocument(getter_AddRefs(domDoc));
}
I have tried to get nsIDOMDocumentXBL pointer by QIing nsIDOMDocument pointer(domDoc in my example) but it fails with Error code 0x80004002 (2147500034) i.e.NS_ERROR_NO_INTERFACE.
How do I get the tab element corresponding to document load request.
Could any one please help me?
Thanks in Advance,
Vaibhav D. Gade.
IF I understood the question correctly and you want a for a content window, you probably need https://developer.mozilla.org/en/Working_with_windows_in_chrome_code#Accessing_the_elements_of_the_top-level_document_from_a_child_window to get the chrome window, then run the implementation of gBrowser.getBrowserForDocument in the chrome window.
You'd save yourself a lot of time if you stopped writing C++ and switched to JS for such things.