Closed jeremycarroll closed 4 years ago
For posterity, this affects program service quite frequently and probably every other service: https://docs.google.com/document/d/1L35IIDNzFUlMn8kjbU4o9-dBJGgjmFlH3NKMABvxXKo/edit#
Note my comments with images are a way to get the images into the documentation
@amory-coursera one final question is the version number. I started by viewing this as a bug fix, taking the version to 2.1.8; we could say that the developer documentation is a new feature, taking it to 2.2.0; or we could even say that the (belated) honesty about gradle and maven not being supported is not backwardly compatible taking it to 3.0.0.
As per slack conversation,
Ask someone with write access to:
merge PR
grant me write access
Fixing a Deadlock and Documentation
I ended up finding it difficult to move from my initial fix, to a testable deployable change, that I had run with the unit tests in Coursera. Hence this PR now covers two very different issues:
Actual Intended Change
This PR addresses the deadlock seen in a Coursera internal diff. This deadlock appears to be an instance of the lazy value initialization order problem described in this SIP
There are two new pieces of code:
The diff adds a test case exhibiting the deadlock
The laziness of the lazy field
properties
ofScalaEnumTemplate
is re-implemented explicitly with no locking, so that multiple threads can initialize the value concurrently, with the last thread winning. This is semantically safe since all threads compute the same value. It resolves the deadlock because one of the locks no longer exists.Prior to the implementation change, the
raceWithNameWithName
test usually (but not always) fails with the two critical threads having the following state - showing the deadlock between a class initialization lock for a companion object and the lock for the lazy property.The test case, CompanionRaceTest, is a version of this problem with no reference to any Coursera code. It uses two lazy fields and a companion class. If setting the
WORKAROUND
field tofalse
, then the test fails, while it istrue
the test case uses the same workaround as is implemented in this diff. This is hence a variant of the Scala lazy value problem.Documentation and Build Changes
As I approach my real task, it became clear that the documentation was incomplete and messy.
I have made the following high-level changes to address these problems:
full
as a custom cross-version commandcourier-maven-plugin
andcourier-gradle-plugin
are not supported, removing the gradle support from some of the scripts (but clarifying and improving the documentation in the gradle subproject itself)Testing
Testing Actual Change
The new unit test and running the tests on the companion PR over Coursera's services: many times, none of which deadlocked.
Testing Other Changes