Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ready API #229

Merged
merged 3 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {

// Wait for the owning module to be ready.
if !moduleIsReady(e.BelongsTo) {
http.Error(w, "The API endpoint is not ready yet or the its module is not enabled. Please try again later.", http.StatusServiceUnavailable)
http.Error(w, "The API endpoint is not ready yet or the its module is not enabled. Reload (F5) to try again.", http.StatusServiceUnavailable)
return
}

Expand Down
25 changes: 25 additions & 0 deletions api/endpoints_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"bytes"
"context"
"errors"
"fmt"
"net/http"
"os"
Expand All @@ -11,6 +12,7 @@ import (
"time"

"github.com/safing/portbase/info"
"github.com/safing/portbase/modules"
"github.com/safing/portbase/utils/debug"
)

Expand All @@ -25,6 +27,16 @@ func registerDebugEndpoints() error {
return err
}

if err := RegisterEndpoint(Endpoint{
Path: "ready",
Read: PermitAnyone,
ActionFunc: ready,
Name: "Ready",
Description: "Check if Portmaster has completed starting and is ready.",
}); err != nil {
return err
}

if err := RegisterEndpoint(Endpoint{
Path: "debug/stack",
Read: PermitAnyone,
Expand Down Expand Up @@ -118,9 +130,22 @@ You can easily view this data in your browser with this command (with Go install

// ping responds with pong.
func ping(ar *Request) (msg string, err error) {
// TODO: Remove upgrade to "ready" when all UI components have transitioned.
if modules.IsStarting() || modules.IsShuttingDown() {
return "", ErrorWithStatus(errors.New("portmaster is not ready, reload (F5) to try again"), http.StatusTooEarly)
}

return "Pong.", nil
}

// ready checks if Portmaster has completed starting.
func ready(ar *Request) (msg string, err error) {
if modules.IsStarting() || modules.IsShuttingDown() {
return "", ErrorWithStatus(errors.New("portmaster is not ready, reload (F5) to try again"), http.StatusTooEarly)
}
return "Portmaster is ready.", nil
}

// getStack returns the current goroutine stack.
func getStack(_ *Request) (data []byte, err error) {
buf := &bytes.Buffer{}
Expand Down
2 changes: 1 addition & 1 deletion api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func (mh *mainHandler) handle(w http.ResponseWriter, r *http.Request) error {
// Wait for the owning module to be ready.
if moduleHandler, ok := handler.(ModuleHandler); ok {
if !moduleIsReady(moduleHandler.BelongsTo()) {
http.Error(lrw, "The API endpoint is not ready yet. Please try again later.", http.StatusServiceUnavailable)
http.Error(lrw, "The API endpoint is not ready yet. Reload (F5) to try again.", http.StatusServiceUnavailable)
return nil
}
}
Expand Down
5 changes: 5 additions & 0 deletions modules/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ func SetGlobalPrepFn(fn func() error) {
}
}

// IsStarting returns whether the initial global start is still in progress.
func IsStarting() bool {
return !initialStartCompleted.IsSet()
}

// Start starts all modules in the correct order. In case of an error, it will automatically shutdown again.
func Start() error {
if !modulesLocked.SetToIf(false, true) {
Expand Down
Loading