func (u *unitSetter) Read(p []byte) (n int, err error) {
n, err = u.ReadCloser.Read(p)
here.Is(n)
if err == io.EOF {
// record that the unit is now using this version of the resource
if err := u.persist.SetUnitResource(u.unit.Name(), u.resource); err != nil {
msg := "Failed to record that unit %q is using resource %q revision %v"
logger.Errorf(msg, u.unit.Name(), u.resource.Name, u.resource.RevisionString())
}
} else {
u.progress += int64(n)
// TODO(ericsnow) Don't do this every time?
if err := u.persist.SetUnitResourceProgress(u.unit.Name(), u.pending, u.progress); err != nil {
logger.Errorf("failed to track progress: %v", err)
}
}
return n, err
}
That u.persist.SetUnitResourceProgress involves a database transaction and is called every 8kb of data, so for a large file there is massive contention on the database. Comment it out and the file is read at the expected rate (can read 800M to /dev/null in ~2 seconds).
I will propose a change that updates the progress once a second. Looks like the entire HTTP request takes about 5 seconds for an 800MB file.
github. com/juju/ juju/resource/ state/resource. go contains:
func (u *unitSetter) Read(p []byte) (n int, err error) { Read(p) SetUnitResource (u.unit. Name(), u.resource); err != nil { Errorf( msg, u.unit.Name(), u.resource.Name,
u.resource. RevisionString( )) SetUnitResource Progress( u.unit. Name(), u.pending, u.progress); err != nil { Errorf( "failed to track progress: %v", err)
n, err = u.ReadCloser.
here.Is(n)
if err == io.EOF {
// record that the unit is now using this version of the resource
if err := u.persist.
msg := "Failed to record that unit %q is using resource %q revision %v"
logger.
}
} else {
u.progress += int64(n)
// TODO(ericsnow) Don't do this every time?
if err := u.persist.
logger.
}
}
return n, err
}
That u.persist. SetUnitResource Progress involves a database transaction and is called every 8kb of data, so for a large file there is massive contention on the database. Comment it out and the file is read at the expected rate (can read 800M to /dev/null in ~2 seconds).
I will propose a change that updates the progress once a second. Looks like the entire HTTP request takes about 5 seconds for an 800MB file.