[#903] Report the grant instead of inferring it, and read the conflict class once
Round 3 of review on #904.
Report rather than infer. The line that says "the first replay, granted past it" was derived from
elapsed >= window, which coincides with the grant only while that grant is the sole way past the
window; grantedPastTheWindow() is now a question of its own, and both the loop and the log ask it.
Read the class once. write() calls conflictOf() and hands the result to replayReason() and to the
bounds, which no longer take a driver name at all: three walks of the chains per failed attempt
become one, two callers can no longer drift into disagreeing about the same failure, and the warn
is guarded by isWarnEnabled() so a server with no error-log publisher builds none of it.
Name the link the class was decided on. conflictOf() keeps the most specific class in the chains
while conflictSummary() named the first conflict it met, so a lock wait timeout under a bare class
40 wrapper logged "error 0" - the 1205 that chose the bound never appeared.
Delete replayable() and isRetryableConflict(). Both had become wrappers no src/main caller reaches
after the split; their content is one comparison at each site.
State the MySQL trade in the javadoc of the window rather than in a test row: at the stock
innodb_lock_wait_timeout a lock wait timeout is reported past the window on the first check and
gets no grant, so it is never replayed. Master behaved the same way and said nothing.
Advance the scripted clock of testWriteDrivesTheRetryLoop per attempt instead of per read, which
retires the assertion on the number of reads and with it the coupling to the fixture. Both mutants
still die: deleting the grant gives "attempts made expected [2] but found [1]", and a startedAt
moved inside the loop gives "expected [3] but found [10]".
Filed #915 for bounding the attempt itself - the change that retires the grant, the Conflict enum
and the driver-keyed vendor number together - with the 1222/55P03 classification it has to carry.