Skip to content

Commit

Permalink
Added a maximum payload size constraint.
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-cohere committed Jul 23, 2024
1 parent 5a68669 commit 621a236
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type serviceConfig struct {
// maximum number of allowed incoming connections
// default: 100
MaxConnections int `json:"max_connections,omitempty" yaml:"max_connections,omitempty"`
// maximum size of requested payload for transfer, past which transfer
// requests are rejected (gigabytes)
MaxPayloadSize int `json:"max_payload_size,omitempy" yaml:"max_payload_size,omitempty"`
// polling interval for checking transfer statuses (milliseconds)
// default: 1 minute
PollInterval int `json:"poll_interval" yaml:"poll_interval"`
Expand Down Expand Up @@ -80,6 +83,7 @@ func readConfig(bytes []byte) error {
var conf configFile
conf.Service.Port = 8080
conf.Service.MaxConnections = 100
conf.Service.MaxPayloadSize = 100
conf.Service.PollInterval = int(time.Minute / time.Millisecond)
conf.Service.DeleteAfter = 7 * 24 * 3600
err := yaml.Unmarshal(bytes, &conf)
Expand Down
1 change: 1 addition & 0 deletions dts.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
service:
port: 8080 # port on which the service listenѕ
max_connections: 100 # maximum number of incoming HTTP connections
max_payload_size: 100 # limit (if any) on DTS payload size (gigabytes)
poll_interval: 60000 # interval at which DTS checks transfer statuses (ms)
endpoint: globus-local # name of endpoint used for manifest generation
data_dir: /path/to/dir # directory DTS uses for internal data storage
Expand Down
25 changes: 25 additions & 0 deletions tasks/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ type taskType struct {
CompletionTime time.Time // time at which the transfer completed
}

// This error type is returned when a payload is requested that is too large.
type PayloadTooLargeError struct {
size int // size of the requested payload in gigabytes
}

func (e PayloadTooLargeError) Error() string {
return fmt.Sprintf("Requested payload is too large: %d GB (limit is %d GB).",
e.size, config.Service.MaxPayloadSize)
}

// computes the size of a payload for a transfer task (in gigabytes)
func payloadSize(resources []DataResource) int {
var size uint64
for _, resource := range resources {
size += uint64(resource.Bytes)
}
return int(size / (1024 * 1024))
}

// starts a task going, initiating staging if needed
func (task *taskType) start() error {
source, err := databases.NewDatabase(task.Orcid, task.Source)
Expand All @@ -94,6 +113,12 @@ func (task *taskType) start() error {
return err
}

// make sure the size of the payload doesn't exceed our specified limit
size := payloadSize(task.Resources) // (in GB)
if size > config.Service.MaxPayloadSize {
return &PayloadTooLargeError{size: size}
}

// are the files already staged? (only works for public data)
sourceEndpoint, err := source.Endpoint()
if err != nil {
Expand Down

0 comments on commit 621a236

Please sign in to comment.