Merge pull request #2782 from davotoula/fix/scheduled-posts-lint-fixes

Lint and sonar cleanup on scheduled-posts
This commit is contained in:
Vitor Pamplona
2026-05-08 08:13:17 -04:00
committed by GitHub
4 changed files with 34 additions and 20 deletions
@@ -253,15 +253,21 @@ class ScheduledPostStore(
try { try {
mapper.writeValue(tmp, ScheduledPostFile(version = 1, posts = snapshot)) mapper.writeValue(tmp, ScheduledPostFile(version = 1, posts = snapshot))
if (!tmp.renameTo(storageFile)) { if (!tmp.renameTo(storageFile)) {
storageFile.delete() if (!storageFile.delete()) {
Log.w(TAG) { "Failed to delete existing $storageFile before rename retry" }
}
if (!tmp.renameTo(storageFile)) { if (!tmp.renameTo(storageFile)) {
Log.e(TAG, "Failed to rename $tmp to $storageFile") Log.e(TAG, "Failed to rename $tmp to $storageFile")
tmp.delete() if (!tmp.delete()) {
Log.w(TAG) { "Failed to clean up temp file $tmp after rename failure" }
}
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Failed to persist scheduled posts to $storageFile", e) Log.e(TAG, "Failed to persist scheduled posts to $storageFile", e)
tmp.delete() if (!tmp.delete()) {
Log.w(TAG) { "Failed to clean up temp file $tmp after persist exception" }
}
} }
} }
@@ -198,15 +198,14 @@ class ScheduledPostWorker(
): Int { ): Int {
val deadline = System.currentTimeMillis() + OK_TIMEOUT_SEC * 1000 val deadline = System.currentTimeMillis() + OK_TIMEOUT_SEC * 1000
while (System.currentTimeMillis() < deadline) { while (System.currentTimeMillis() < deadline) {
val pending = client.pendingPublishRelaysFor(eventId)
// null means the outbox dropped the entry — every relay either OK'd // null means the outbox dropped the entry — every relay either OK'd
// or hit the discard cap (replaced/pow/deleted/invalid). Treat as full ack. // or hit the discard cap (replaced/pow/deleted/invalid). Treat as full ack.
if (pending == null) return totalRelays val pending = client.pendingPublishRelaysFor(eventId) ?: return totalRelays
val acked = totalRelays - pending.size val acked = totalRelays - pending.size
if (acked > 0) return acked if (acked > 0) return acked
delay(OK_POLL_MS) delay(OK_POLL_MS)
} }
val pending = client.pendingPublishRelaysFor(eventId) val pending = client.pendingPublishRelaysFor(eventId) ?: return totalRelays
return if (pending == null) totalRelays else totalRelays - pending.size return totalRelays - pending.size
} }
} }
@@ -66,6 +66,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -77,12 +78,11 @@ import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@@ -97,6 +97,7 @@ import com.vitorpamplona.amethyst.service.scheduledposts.ScheduledPost
import com.vitorpamplona.amethyst.service.scheduledposts.ScheduledPostStatus import com.vitorpamplona.amethyst.service.scheduledposts.ScheduledPostStatus
import com.vitorpamplona.amethyst.service.scheduledposts.ScheduledPostWorker import com.vitorpamplona.amethyst.service.scheduledposts.ScheduledPostWorker
import com.vitorpamplona.amethyst.ui.components.SwipeToDeleteWithConfirmation import com.vitorpamplona.amethyst.ui.components.SwipeToDeleteWithConfirmation
import com.vitorpamplona.amethyst.ui.components.util.setText
import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.navs.INav
import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.Route
import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar
@@ -107,6 +108,7 @@ import com.vitorpamplona.amethyst.ui.note.timeAheadNoDot
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.stringRes
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.time.Instant import java.time.Instant
import java.time.LocalDate import java.time.LocalDate
import java.time.ZoneId import java.time.ZoneId
@@ -373,7 +375,8 @@ private fun ScheduledPostCardExpandedPanel(
onDelete: () -> Unit, onDelete: () -> Unit,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val clipboard = LocalClipboardManager.current val clipboardManager = LocalClipboard.current
val scope = rememberCoroutineScope()
val eventId = remember(post.id) { extractEventId(post) } val eventId = remember(post.id) { extractEventId(post) }
Column( Column(
@@ -410,7 +413,7 @@ private fun ScheduledPostCardExpandedPanel(
.combinedClickable( .combinedClickable(
onClick = {}, onClick = {},
onLongClick = { onLongClick = {
clipboard.setText(AnnotatedString(eventId)) scope.launch { clipboardManager.setText(eventId) }
Toast Toast
.makeText( .makeText(
context, context,
@@ -56,6 +56,12 @@ private const val EXIT_OK = 0
private const val EXIT_FAIL = 1 private const val EXIT_FAIL = 1
private const val EXIT_UNSUPPORTED = 127 private const val EXIT_UNSUPPORTED = 127
// Sentinel rendered for null/empty env-var values in boot-line logging.
private const val UNSET_LABEL = "(unset)"
// IANA ALPN identifier for HTTP/0.9-over-QUIC used by quic-interop-runner.
private const val ALPN_HQ_INTEROP = "hq-interop"
private const val HANDSHAKE_TIMEOUT_SEC = 10L private const val HANDSHAKE_TIMEOUT_SEC = 10L
// Multiconnect's per-iteration handshake timeout. The runner's // Multiconnect's per-iteration handshake timeout. The runner's
@@ -120,11 +126,11 @@ fun main() {
System.err.println( System.err.println(
"[boot] DEBUG=1; writerDebugEnabled=true; build_id=" + "[boot] DEBUG=1; writerDebugEnabled=true; build_id=" +
"${com.vitorpamplona.quic.connection.WRITER_DEBUG_BUILD_ID}; " + "${com.vitorpamplona.quic.connection.WRITER_DEBUG_BUILD_ID}; " +
"TESTCASE=${System.getenv("TESTCASE") ?: "(unset)"}; " + "TESTCASE=${System.getenv("TESTCASE") ?: UNSET_LABEL}; " +
"ROLE=${System.getenv("ROLE") ?: "(unset)"}", "ROLE=${System.getenv("ROLE") ?: UNSET_LABEL}",
) )
} else { } else {
System.err.println("[boot] DEBUG=${debugEnv ?: "(unset)"} writerDebugEnabled=false") System.err.println("[boot] DEBUG=${debugEnv ?: UNSET_LABEL} writerDebugEnabled=false")
} }
val role = System.getenv("ROLE") ?: "client" val role = System.getenv("ROLE") ?: "client"
@@ -150,8 +156,8 @@ fun main() {
System.err.println("testcase: $testcase") System.err.println("testcase: $testcase")
System.err.println("requests: $requests") System.err.println("requests: $requests")
System.err.println("downloads dir: ${downloadsDir.absolutePath} (exists=${downloadsDir.isDirectory})") System.err.println("downloads dir: ${downloadsDir.absolutePath} (exists=${downloadsDir.isDirectory})")
System.err.println("sslkeylogfile: ${keyLogPath ?: "(unset)"}") System.err.println("sslkeylogfile: ${keyLogPath ?: UNSET_LABEL}")
System.err.println("qlogdir: ${qlogDir?.absolutePath ?: "(unset)"}") System.err.println("qlogdir: ${qlogDir?.absolutePath ?: UNSET_LABEL}")
} }
val cipherSuites = val cipherSuites =
@@ -367,7 +373,7 @@ internal enum class Alpn(
* on a fresh bidi stream, server returns the body, FIN both sides. No * on a fresh bidi stream, server returns the body, FIN both sides. No
* control stream, no QPACK, no SETTINGS. Used for handshake / chacha20 / * control stream, no QPACK, no SETTINGS. Used for handshake / chacha20 /
* transfer / loss-variant testcases. */ * transfer / loss-variant testcases. */
HQ_INTEROP("hq-interop".encodeToByteArray()), HQ_INTEROP(ALPN_HQ_INTEROP.encodeToByteArray()),
} }
private fun runTransferTest( private fun runTransferTest(
@@ -478,7 +484,7 @@ private fun runTransferTest(
Http3GetClient(conn, driver).also { it.init(scope) } Http3GetClient(conn, driver).also { it.init(scope) }
} }
"hq-interop" -> { ALPN_HQ_INTEROP -> {
HqInteropGetClient(conn, driver) HqInteropGetClient(conn, driver)
} }
@@ -934,7 +940,7 @@ private suspend fun runOneResumptionConnection(
Http3GetClient(conn, driver).also { it.init(scope) } Http3GetClient(conn, driver).also { it.init(scope) }
} }
"hq-interop" -> { ALPN_HQ_INTEROP -> {
HqInteropGetClient(conn, driver) HqInteropGetClient(conn, driver)
} }
@@ -1111,7 +1117,7 @@ private fun runMulticonnectTest(
Http3GetClient(conn, driver).also { it.init(scope) } Http3GetClient(conn, driver).also { it.init(scope) }
} }
"hq-interop" -> { ALPN_HQ_INTEROP -> {
HqInteropGetClient(conn, driver) HqInteropGetClient(conn, driver)
} }