mirror of
https://github.com/chmouel/liseur.git
synced 2026-10-16 12:50:22 +00:00
fix: let a saved answer be accepted while the network is blocked
When two devices disagree about where a book was left off, Liseur offers the reader both positions. Accepting the other device's is purely local work: the position was fetched and written down by an earlier sync, so choosing it changes nothing but this phone, which is why it works on a plane. The new local network check was refusing it anyway. Sending this device's position, which does reach the server, is still refused.
This commit is contained in:
parent
3270d7eba6
commit
d333ea9dca
3 changed files with 31 additions and 33 deletions
|
|
@ -59,28 +59,20 @@ class LocalNetworkGuardedSync(
|
|||
}
|
||||
|
||||
/**
|
||||
* Settling a conflict sends the answer to the server, so it is
|
||||
* guarded too.
|
||||
* Keeping this device's position sends it to the server, so it is
|
||||
* guarded; taking the server's is not.
|
||||
*
|
||||
* Both of these are reached from the reader's own tap, and both
|
||||
* already answer `Failed(Offline)` when there is no network at all.
|
||||
* A blocked one is the same thing said differently: the write is
|
||||
* not going to arrive, and a timeout the reader watches is the
|
||||
* worst way to tell them so. The status line is left alone, as it
|
||||
* is for a preview.
|
||||
* The asymmetry is the two operations', not this class's. Taking
|
||||
* the server's position applies an answer an earlier run already
|
||||
* brought back and wrote down, and touches nothing but this
|
||||
* phone's database — which is why it works on a plane, and must go
|
||||
* on working behind a blocked network for the same reason. Keeping
|
||||
* this device's dials, and already answers `Failed(Offline)` when
|
||||
* there is no network at all; a blocked one is that said
|
||||
* differently, and a timeout the reader sits and watches is the
|
||||
* worst way to say it. The status line is left alone, as it is for
|
||||
* a preview: one book being settled is not a run.
|
||||
*/
|
||||
override suspend fun takeRemotePosition(
|
||||
bookUrl: String,
|
||||
atRevision: Long,
|
||||
peerId: String?,
|
||||
expectedAccountKey: String?,
|
||||
): ResolveOutcome =
|
||||
if (blocked()) {
|
||||
ResolveOutcome.Failed(SyncFailure.LocalNetworkBlocked)
|
||||
} else {
|
||||
delegate.takeRemotePosition(bookUrl, atRevision, peerId, expectedAccountKey)
|
||||
}
|
||||
|
||||
override suspend fun keepLocalPosition(bookUrl: String, peerId: String?): ResolveOutcome =
|
||||
if (blocked()) {
|
||||
ResolveOutcome.Failed(SyncFailure.LocalNetworkBlocked)
|
||||
|
|
|
|||
|
|
@ -79,13 +79,15 @@ class LocalNetworkGuardedSyncTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* Settling a conflict writes the answer to the server, so it is
|
||||
* refused too rather than left to sit on a timeout the reader is
|
||||
* watching. The status line is not touched: this is one book being
|
||||
* settled, not a run.
|
||||
* Keeping this device's position writes it to the server, so it is
|
||||
* refused rather than left to sit on a timeout the reader is
|
||||
* watching. Taking the server's applies an answer an earlier run
|
||||
* already wrote down and touches nothing but this phone, so it goes
|
||||
* through — the same reason it works on a plane. Neither touches
|
||||
* the status line: this is one book being settled, not a run.
|
||||
*/
|
||||
@Test
|
||||
fun `settling a conflict is refused rather than dialled`() = runTest {
|
||||
fun `sending an answer is refused but accepting one still works`() = runTest {
|
||||
val peer = FakePeer(PeerPositionSync.CATALOG)
|
||||
val reporting = SyncReporting()
|
||||
val guarded = guard(peer, reporting, "http://192.168.1.20:8083")
|
||||
|
|
@ -94,8 +96,8 @@ class LocalNetworkGuardedSyncTest {
|
|||
val taken = guarded.takeRemotePosition("book", 1L, null, null)
|
||||
|
||||
assertEquals(ResolveOutcome.Failed(SyncFailure.LocalNetworkBlocked), kept)
|
||||
assertEquals(ResolveOutcome.Failed(SyncFailure.LocalNetworkBlocked), taken)
|
||||
assertEquals(0, peer.resolutions)
|
||||
assertEquals(ResolveOutcome.Done, taken)
|
||||
assertEquals(1, peer.resolutions)
|
||||
assertEquals(PositionSyncStatus.Idle, reporting.statusOf(PeerPositionSync.CATALOG))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue