ConfD User Community

Cdb_start_session with CDB_LOCK_WAIT does not work as expected

Hello,

I am executing 2 threads . Both share same data socket.
I am trying to acquire session on both of them at same time but I use the flags as CDB_LOCK_REQUEST and CDB_LOCK_WAIT.

What I expect is one of the thread waits for session to be available. However I am getting error stating NEW_SESSION should be called after END_SESSION.

Is there anything wrong in understanding.

Following is given in Confd User Guide:

int cdb_start_session2(int sock, enum cdb_db_type db, int flags); API explanation

“In all cases of using CDB_LOCK_SESSION or CDB_LOCK_REQUEST described above, adding the
CDB_LOCK_WAIT flag means that instead of failing with CONFD_ERR_LOCKED if the lock can
not be obtained immediately, requests will wait for the lock to become available. When used with
CDB_LOCK_SESSION it pertains to cdb_start_session2() itself, with CDB_LOCK_REQUEST
it pertains to the individual requests.”

Copy paste from the ConfD UG:
When we use e.g. the CDB or MAAPI APIs, the application must make sure that each thread has its own sockets. I.e. the ConfD API functions are thread-safe as such, but multiple threads using them with the same socket will have unpredictable results, just as multiple threads using the read() and write() system calls on the same file descriptor in general will. In the ConfD case, one thread may end up getting the response to a request from another, or even a part of that response, which will result in errors that can be very difficult to debug.

Thanks Cohult…

Just one doubt…

If every thread has its own socket… Then what is the use of CDB_LOCK_REQUEST|CDB_LOCK_WAIT as thread itself can be synchronized …

When you use the CDB API to read config data, you don’t want a transaction from a northbound interface, NETCONF, CLI, MAAPI, etc, to write to CDB while you are reading, so using start session you obtain the transaction write lock. If the lock is taken by a write transaction from a northbound interface you will have to wait for that transaction to finish writing and release the lock. A write lock taken from another CDB read session will not prevent you from taking sharing the lock with the other CDB session. The lock will be released by the session done last. The transaction write lock can be taken for the duration of the CDB read session or per read request, e.g CDB_get(), CDB_get_values() etc.

Note that if your application is a CDB subscriber and is acting on a config change event, the transaction write lock is already taken for you while you do a cdb_get_modifications(), cdb_diff_iterate(), start session + get values etc. at least until you call cdb_sync_subscription()

From the confd_lib_cdb man page:

CDB_LOCK_WAIT flag means that instead of failing with CONFD_ERR_LOCKED if the lock can not be obtained immediately, requests will wait for the lock to become available. When used with CDB_LOCK_SESSION it pertains to cdb_start_session2() itself, with CDB_LOCK_REQUEST it pertains to the individual requests.

CDB_LOCK_REQUEST obtains a read lock only for the duration of each read request. This means that values of elements read in different requests may be inconsistent with each other, and the consequences of this must be carefully considered.

Thats explains a lot…

But in contrast to your explanation…

My 2 threads are only reading read… No write… No one else is writing to DB…

Still I fail to start session over operational data… Error thrown is
“E=21-must call END_SESSION before NEW_SESSION”

What do you mean by “in contrast”?
You are using the same data socket with two threads. Regardless of flags, oper or config, read or write, don’t do that. Use one socket per thread.

In contrast… I meant There is no write/read operation on config data.

I am just trying data read on operational data.

My understanding was multiple reads can be performed using same socket. However as you clarify I MUST use different socket per thread, I will try that approach.

Thanks for explaining…