package process import ( "fmt" "strconv" "strings" ) // WorkerKey is the unique identity of ONE forward's worker process: // // "~~" // // The per-forward worker model gives every link its own frpc process, config // file and log file. This fixes the multi-node proxy-name fight of the old // per-remote model (every node rendered the SAME proxy list and raced to // register them on frps -> "proxy already exists"), and isolates faults: one // crashing forward can no longer take its siblings down. // // '~' is a legal filename character on every supported OS (including Windows, // unlike ':') and is rare in user-chosen node names. ParseWorkerKey rejects // malformed keys so callers fail loudly instead of silently mis-rendering. func WorkerKey(local, remote string, port int) string { return fmt.Sprintf("%s~%s~%d", local, remote, port) } // ParseWorkerKey splits a worker key back into its (local, remote, port) // forward triple. ok=false for anything that is not a well-formed key // (e.g. legacy per-remote worker names). func ParseWorkerKey(key string) (local, remote string, port int, ok bool) { parts := strings.Split(key, "~") if len(parts) != 3 { return "", "", 0, false } p, err := strconv.Atoi(parts[2]) if err != nil || parts[0] == "" || parts[1] == "" || p <= 0 { return "", "", 0, false } return parts[0], parts[1], p, true }