server switcher is broken
This commit is contained in:
@@ -121,6 +121,7 @@ final class Connection {
|
||||
let overlays = Overlays()
|
||||
var phase: Phase = .starting
|
||||
@ObservationIgnored private var stopped = false
|
||||
@ObservationIgnored private var restarting = false
|
||||
|
||||
init(origin: URL) {
|
||||
self.origin = origin
|
||||
@@ -144,13 +145,32 @@ final class Connection {
|
||||
}
|
||||
|
||||
private func start() async {
|
||||
while !stopped, !(await attempt()) {
|
||||
let old = store
|
||||
while !stopped, !(await attempt(old)) {
|
||||
try? await Task.sleep(for: .seconds(2))
|
||||
}
|
||||
if let old {
|
||||
await old.stop()
|
||||
}
|
||||
}
|
||||
|
||||
private func attempt() async -> Bool {
|
||||
let store = Store(api: API(origin: origin))
|
||||
private func reconnected(_ startedAt: Date) {
|
||||
guard !restarting else {
|
||||
return
|
||||
}
|
||||
Task {
|
||||
guard let status = try? await API(origin: origin).client.getStatus().ok.body.json, status.startedAt != startedAt, !stopped, !restarting else {
|
||||
return
|
||||
}
|
||||
log.notice("\(self.origin.absoluteString, privacy: .public) restarted, reloading")
|
||||
restarting = true
|
||||
await start()
|
||||
restarting = false
|
||||
}
|
||||
}
|
||||
|
||||
private func attempt(_ old: Store?) async -> Bool {
|
||||
let store = Store(api: API(origin: origin), images: old?.images ?? ImageDrafts())
|
||||
do {
|
||||
let status = try await store.api.client.getStatus().ok.body.json
|
||||
async let me: Void = store.loadMe()
|
||||
@@ -159,17 +179,19 @@ final class Connection {
|
||||
async let lead: Void = store.loadLeadSessions()
|
||||
async let reads: Void = store.loadSummaryReads()
|
||||
_ = try await (me, projects, inbox, lead, reads)
|
||||
store.loadDrafts()
|
||||
try await store.loadFocus()
|
||||
guard !stopped else {
|
||||
await store.stop()
|
||||
return true
|
||||
}
|
||||
store.loadDrafts(from: old)
|
||||
Task {
|
||||
await store.startLeadStream()
|
||||
}
|
||||
phase = .running(store)
|
||||
store.startGlobalStream(after: status.lastEventSeq)
|
||||
store.startGlobalStream(after: status.lastEventSeq) { [weak self] in
|
||||
self?.reconnected(status.startedAt)
|
||||
}
|
||||
store.remote.start()
|
||||
Notifier.shared.deliver()
|
||||
return true
|
||||
@@ -394,7 +416,7 @@ struct ServerWindow: View {
|
||||
MainView()
|
||||
.environment(store)
|
||||
.environment(connection.overlays)
|
||||
.id(connection.origin)
|
||||
.id(ObjectIdentifier(store))
|
||||
}
|
||||
} else {
|
||||
ConnectView(form: form) { connected in
|
||||
@@ -421,6 +443,7 @@ struct ServerWindow: View {
|
||||
ToolbarItem(placement: .principal) {
|
||||
ServerPicker()
|
||||
}
|
||||
.sharedBackgroundVisibility(.hidden)
|
||||
}
|
||||
.toolbar(removing: .title)
|
||||
.focusedSceneValue(\.serverWindow, focus)
|
||||
@@ -499,12 +522,18 @@ private struct ServerChip: View {
|
||||
Badge(count: questions)
|
||||
.help("open questions")
|
||||
}
|
||||
if summaries > 0 {
|
||||
Text("\(summaries) new")
|
||||
.font(Fonts.font(11, weight: 700))
|
||||
.foregroundStyle(Palette.accent)
|
||||
.help("Turn summaries you haven't read")
|
||||
}
|
||||
Text("99")
|
||||
.font(Fonts.font(11, weight: 700))
|
||||
.hidden()
|
||||
.overlay(alignment: .leading) {
|
||||
if summaries > 0 {
|
||||
Text("\(summaries)")
|
||||
.font(Fonts.font(11, weight: 700))
|
||||
.foregroundStyle(Palette.accent)
|
||||
.fixedSize()
|
||||
.help("Turn summaries you haven't read")
|
||||
}
|
||||
}
|
||||
}
|
||||
.foregroundStyle(hover || current ? Palette.text : questions > 0 ? Palette.warn : Palette.muted)
|
||||
.padding(.horizontal, 8)
|
||||
|
||||
@@ -60,7 +60,7 @@ final class Store {
|
||||
var todoBusy: [String: String] = [:]
|
||||
var pickedMembers: [String: String] = [:]
|
||||
private(set) var drafts: Drafts?
|
||||
let images = ImageDrafts()
|
||||
let images: ImageDrafts
|
||||
let imageCache = ImageCache()
|
||||
let events = Listeners<ByreEvent>()
|
||||
let paneFocus: PaneFocus
|
||||
@@ -74,8 +74,9 @@ final class Store {
|
||||
@ObservationIgnored private var stopped = false
|
||||
@ObservationIgnored var changesMemory = ChangesMemory()
|
||||
|
||||
init(api: API) {
|
||||
init(api: API, images: ImageDrafts) {
|
||||
self.api = api
|
||||
self.images = images
|
||||
leadFeed = Feed(shown: { true })
|
||||
paneFocus = PaneFocus(api: api)
|
||||
remote = Remote(api: api)
|
||||
@@ -90,8 +91,8 @@ final class Store {
|
||||
await paneFocus.leave()
|
||||
}
|
||||
|
||||
func loadDrafts() {
|
||||
drafts = Drafts(origin: api.origin, login: me!.login)
|
||||
func loadDrafts(from old: Store?) {
|
||||
drafts = old?.drafts ?? Drafts(origin: api.origin, login: me!.login)
|
||||
drafts!.prune(self)
|
||||
}
|
||||
|
||||
@@ -565,13 +566,14 @@ final class Store {
|
||||
})
|
||||
}
|
||||
|
||||
func startGlobalStream(after: Int64) {
|
||||
func startGlobalStream(after: Int64, reconnected: @escaping () -> Void) {
|
||||
globalStream = EventStream(api: api, after: after, lead: false, onEvent: { [weak self] ev in
|
||||
self?.handleEvent(ev)
|
||||
}, onState: { [weak self] up in
|
||||
self?.connected = up
|
||||
if up {
|
||||
self?.paneFocus.reconnected()
|
||||
reconnected()
|
||||
}
|
||||
}, onReady: {})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user