Streaming Transfers (#153)
This commit is contained in:
128
server/transfer/transfer.go
Normal file
128
server/transfer/transfer.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package transfer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/mitchellh/colorstring"
|
||||
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"github.com/pterodactyl/wings/system"
|
||||
)
|
||||
|
||||
// Status represents the current status of a transfer.
|
||||
type Status string
|
||||
|
||||
// String satisfies the fmt.Stringer interface.
|
||||
func (s Status) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
const (
|
||||
// StatusPending is the status of a transfer when it is first created.
|
||||
StatusPending Status = "pending"
|
||||
// StatusProcessing is the status of a transfer when it is currently in
|
||||
// progress, such as when the archive is being streamed to the target node.
|
||||
StatusProcessing Status = "processing"
|
||||
|
||||
// StatusCancelling is the status of a transfer when it is in the process of
|
||||
// being cancelled.
|
||||
StatusCancelling Status = "cancelling"
|
||||
|
||||
// StatusCancelled is the final status of a transfer when it has been
|
||||
// cancelled.
|
||||
StatusCancelled Status = "cancelled"
|
||||
// StatusFailed is the final status of a transfer when it has failed.
|
||||
StatusFailed Status = "failed"
|
||||
// StatusCompleted is the final status of a transfer when it has completed.
|
||||
StatusCompleted Status = "completed"
|
||||
)
|
||||
|
||||
// Transfer represents a transfer of a server from one node to another.
|
||||
type Transfer struct {
|
||||
// ctx is the context for the transfer.
|
||||
ctx context.Context
|
||||
// cancel is used to cancel all ongoing transfer operations for the server.
|
||||
cancel *context.CancelFunc
|
||||
|
||||
// Server associated with the transfer.
|
||||
Server *server.Server
|
||||
// status of the transfer.
|
||||
status *system.Atomic[Status]
|
||||
|
||||
// archive is the archive that is being created for the transfer.
|
||||
archive *Archive
|
||||
}
|
||||
|
||||
// New returns a new transfer instance for the given server.
|
||||
func New(ctx context.Context, s *server.Server) *Transfer {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
return &Transfer{
|
||||
ctx: ctx,
|
||||
cancel: &cancel,
|
||||
|
||||
Server: s,
|
||||
status: system.NewAtomic(StatusPending),
|
||||
}
|
||||
}
|
||||
|
||||
// Context returns the context for the transfer.
|
||||
func (t *Transfer) Context() context.Context {
|
||||
return t.ctx
|
||||
}
|
||||
|
||||
// Cancel cancels the transfer.
|
||||
func (t *Transfer) Cancel() {
|
||||
status := t.Status()
|
||||
if status == StatusCancelling ||
|
||||
status == StatusCancelled ||
|
||||
status == StatusCompleted ||
|
||||
status == StatusFailed {
|
||||
return
|
||||
}
|
||||
|
||||
if t.cancel == nil {
|
||||
return
|
||||
}
|
||||
|
||||
t.SetStatus(StatusCancelling)
|
||||
(*t.cancel)()
|
||||
}
|
||||
|
||||
// Status returns the current status of the transfer.
|
||||
func (t *Transfer) Status() Status {
|
||||
return t.status.Load()
|
||||
}
|
||||
|
||||
// SetStatus sets the status of the transfer.
|
||||
func (t *Transfer) SetStatus(s Status) {
|
||||
// TODO: prevent certain status changes from happening.
|
||||
// If we are cancelling, then we can't go back to processing.
|
||||
t.status.Store(s)
|
||||
|
||||
t.Server.Events().Publish(server.TransferStatusEvent, s)
|
||||
}
|
||||
|
||||
// SendMessage sends a message to the server's console.
|
||||
func (t *Transfer) SendMessage(v string) {
|
||||
t.Server.Events().Publish(
|
||||
server.TransferLogsEvent,
|
||||
colorstring.Color("[yellow][bold]"+time.Now().Format(time.RFC1123)+" [Transfer System] [Source Node]:[default] "+v),
|
||||
)
|
||||
}
|
||||
|
||||
// Error logs an error that occurred on the source node.
|
||||
func (t *Transfer) Error(err error, v string) {
|
||||
t.Log().WithError(err).Error(v)
|
||||
t.SendMessage(v)
|
||||
}
|
||||
|
||||
// Log returns a logger for the transfer.
|
||||
func (t *Transfer) Log() *log.Entry {
|
||||
if t.Server == nil {
|
||||
return log.WithField("subsystem", "transfer")
|
||||
}
|
||||
return t.Server.Log().WithField("subsystem", "transfer")
|
||||
}
|
||||
Reference in New Issue
Block a user