Question regarding a thread issue that was potentially fixed
Hello! I have a question that would be for you @kubo.
We have a production application using this gem, here are the specs:
ruby v2.7.5 rails v5.2.6.3 ruby-oci8 v2.2.9 oracle db v12
We tried upgrading to rails 6 (6.0.4.7) 2 weeks ago and we started having a lot of errors like this: executing in another thread which is raised by the C code of this gem.
We spent a lot of time trying to understand why (we still don't, up to this day), but we did find that a specific commit that solves the issue. That would be this commit: https://github.com/kubo/ruby-oci8/commit/031cab52f95e9d3ea5229ed0e465c95a7e94dcaa.
We were wondering if you would have an explanation of what could have happened here? We were wondering if the changes in ext/oci8/apiwrap.c.tmpl in that commit would be the fix?
Without the full context of how our application if configured, I guess you might not have an answer, but I was curious to ask anyway.
Thank you!
I'm not sure but it may be fixed by inserting write barriers. (https://bugs.ruby-lang.org/projects/ruby-master/wiki/RGenGC)
before https://github.com/kubo/ruby-oci8/commit/031cab52f95e9d3ea5229ed0e465c95a7e94dcaa:
- Set
svcctx->executing_threadwith write barrier.RB_OBJ_WRITE(parg->svcctx->base.self, &parg->svcctx->executing_thread, rb_thread_current())inoci8lib.c - Enter a blocking region. (It releases a global VM lock to allow other ruby threads run.)
- Execute an OCI function which may take a long time.
- Unset
svcctx->executing_threadwithout write barrier.(svcctx)->executing_thread = Qnilinapiwrap.c.tmpl - Leave the blocking region.
after https://github.com/kubo/ruby-oci8/commit/031cab52f95e9d3ea5229ed0e465c95a7e94dcaa:
- Set
svcctx->executing_threadwith write barrier.RB_OBJ_WRITE(parg->svcctx->base.self, &parg->svcctx->executing_thread, rb_thread_current())inoci8lib.c - Enter a blocking region.
- Execute an OCI function which may take a long time.
- Leave the blocking region.
- Unset
svcctx->executing_threadwith write barrier.RB_OBJ_WRITE(svcctx->base.self, &svcctx->executing_thread, Qnil)inoci8lib.c