Skip to content

Commit

Permalink
Add manual GC
Browse files Browse the repository at this point in the history
  • Loading branch information
livid committed Dec 19, 2024
1 parent 955da9f commit 4bfd44b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Planet/IPFS/IPFSCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ struct IPFSCommand {

static func launchDaemon() -> IPFSCommand {
IPFSCommand(arguments: [
"daemon", "--migrate", "--enable-namesys-pubsub", "--enable-pubsub-experiment", "--enable-gc",
"daemon", "--migrate", "--enable-namesys-pubsub", "--enable-pubsub-experiment",
])
}

Expand Down
31 changes: 31 additions & 0 deletions Planet/IPFS/IPFSDaemon.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
import SwiftyJSON
import UserNotifications
import os

actor IPFSDaemon {
Expand Down Expand Up @@ -659,6 +660,36 @@ actor IPFSDaemon {
try await IPFSDaemon.shared.api(path: "pin/rm", args: ["arg": cid], timeout: 120)
}

func gc() async throws {
Self.logger.info("Running garbage collection")
let result = try await IPFSDaemon.shared.api(path: "repo/gc", timeout: 120)
// Parse JSON result array
let count = String(data: result, encoding: .utf8)?
.components(separatedBy: .newlines)
.filter { $0.contains("Key") }
.count ?? 0

if count > 0 {
// Create and schedule notification
let content = UNMutableNotificationContent()
content.title = "IPFS Garbage Collection Complete"
content.body = "Removed \(count) unused objects"
content.sound = .default
content.interruptionLevel = .timeSensitive

let request = UNNotificationRequest(
identifier: UUID().uuidString,
content: content,
trigger: nil
)

try? await UNUserNotificationCenter.current().add(request)
Self.logger.info("Garbage collection removed \(count) objects")
} else {
Self.logger.info("Garbage collection did not remove any objects")
}
}

func getFile(ipns: String, path: String = "") async throws -> Data {
Self.logger.info("Getting file from IPNS \(ipns)\(path)")
guard let gatewayPort else {
Expand Down
63 changes: 53 additions & 10 deletions Planet/IPFS/Status Views/IPFSStatusView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

import SwiftUI


struct IPFSStatusView: View {
@EnvironmentObject private var ipfsState: IPFSState
@State private var showingGCAlert = false

static let formatter = {
let byteCountFormatter = ByteCountFormatter()
Expand Down Expand Up @@ -45,7 +45,21 @@ struct IPFSStatusView: View {
ProgressView()
.progressViewStyle(.circular)
.controlSize(.small)
} else {
}
else {
Button {
showingGCAlert = true
} label: {
Image(systemName: "arrow.3.trianglepath")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 15)
.foregroundStyle(Color.secondary)
}
.buttonStyle(.plain)
.help("Run IPFS garbage collection.")
.disabled(!ipfsState.online)

if !ipfsState.isShowingStatusWindow {
Button {
IPFSStatusWindowManager.shared.activate()
Expand All @@ -66,14 +80,18 @@ struct IPFSStatusView: View {
Task.detached(priority: .userInitiated) {
if newValue {
try? await IPFSDaemon.shared.launch()
} else {
}
else {
try? await IPFSDaemon.shared.shutdown()
}
await IPFSState.shared.updateStatus()
await MainActor.run {
self.isDaemonOnline = newValue
}
UserDefaults.standard.setValue(newValue, forKey: IPFSState.lastUserLaunchState)
UserDefaults.standard.setValue(
newValue,
forKey: IPFSState.lastUserLaunchState
)
}
}
}
Expand All @@ -83,14 +101,32 @@ struct IPFSStatusView: View {
.padding(.vertical, 12)
.frame(height: 44)
}
.padding(0)
.background(.regularMaterial)
.alert(isPresented: $showingGCAlert) {
Alert(
title: Text("Are you sure you want to manually run garbage collection?"),
message: Text("This will free up disk space by removing unused data."),
primaryButton: .destructive(Text("Run GC")) {
Task {
do {
try await IPFSDaemon.shared.gc()
}
catch {
debugPrint("failed to run gc: \(error)")
}
}
},
secondaryButton: .cancel()
)
}
.frame(width: 280)
.background(.regularMaterial)
.task {
Task.detached(priority: .background) {
do {
try await self.ipfsState.calculateRepoSize()
} catch {
}
catch {
debugPrint("failed to calculate repo size: \(error)")
}
}
Expand All @@ -103,9 +139,15 @@ struct IPFSStatusView: View {
HStack {
Text("Local Gateway")
Spacer(minLength: 1)
Link(self.ipfsState.getGateway(), destination: URL(string: self.ipfsState.getGateway() + "/ipns/k51qzi5uqu5dibstm2yxidly22jx94embd7j3xjstfk65ulictn2ajnjvpiac7")!)
.focusable(false)
.disabled(!self.ipfsState.online)
Link(
self.ipfsState.getGateway(),
destination: URL(
string: self.ipfsState.getGateway()
+ "/ipns/k51qzi5uqu5dibstm2yxidly22jx94embd7j3xjstfk65ulictn2ajnjvpiac7"
)!
)
.focusable(false)
.disabled(!self.ipfsState.online)
}
HStack {
Text("Repo Size")
Expand All @@ -114,7 +156,8 @@ struct IPFSStatusView: View {
ProgressView()
.progressViewStyle(.circular)
.controlSize(.mini)
} else {
}
else {
if let repoSize = ipfsState.repoSize {
Text(Self.formatter.string(fromByteCount: repoSize))
}
Expand Down
2 changes: 1 addition & 1 deletion Planet/versioning.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1 @@
CURRENT_PROJECT_VERSION = 2307
CURRENT_PROJECT_VERSION = 2308

0 comments on commit 4bfd44b

Please sign in to comment.