fix: store/streaming/file: fix os.File leaks in (*StreamService).Listen* methods (#12339)
This change fixes resource leaks that were present due a rigid error return path and didn't invoke .Close until the last line of each method. This change fixes the problem by using a named return error variable and if the return error value is nil, we derive its final value from the unconditionally defer os.File.Close value, which matches the prior logic but now fixes the flaw. Fixes #12336 Fixes #12337 Fixes #12338
This commit is contained in:
parent
9b10b2e6fd
commit
4b6b3b765b
@ -88,12 +88,19 @@ func (fss *StreamingService) Listeners() map[types.StoreKey][]types.WriteListene
|
||||
// ListenBeginBlock satisfies the baseapp.ABCIListener interface
|
||||
// It writes the received BeginBlock request and response and the resulting state changes
|
||||
// out to a file as described in the above the naming schema
|
||||
func (fss *StreamingService) ListenBeginBlock(ctx sdk.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error {
|
||||
func (fss *StreamingService) ListenBeginBlock(ctx sdk.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) (rerr error) {
|
||||
// generate the new file
|
||||
dstFile, err := fss.openBeginBlockFile(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
cerr := dstFile.Close()
|
||||
if rerr == nil {
|
||||
rerr = cerr
|
||||
}
|
||||
}()
|
||||
|
||||
// write req to file
|
||||
lengthPrefixedReqBytes, err := fss.codec.MarshalLengthPrefixed(&req)
|
||||
if err != nil {
|
||||
@ -119,11 +126,8 @@ func (fss *StreamingService) ListenBeginBlock(ctx sdk.Context, req abci.RequestB
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = dstFile.Write(lengthPrefixedResBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
// close file
|
||||
return dstFile.Close()
|
||||
_, err = dstFile.Write(lengthPrefixedResBytes)
|
||||
return err
|
||||
}
|
||||
|
||||
func (fss *StreamingService) openBeginBlockFile(req abci.RequestBeginBlock) (*os.File, error) {
|
||||
@ -139,12 +143,19 @@ func (fss *StreamingService) openBeginBlockFile(req abci.RequestBeginBlock) (*os
|
||||
// ListenDeliverTx satisfies the baseapp.ABCIListener interface
|
||||
// It writes the received DeliverTx request and response and the resulting state changes
|
||||
// out to a file as described in the above the naming schema
|
||||
func (fss *StreamingService) ListenDeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error {
|
||||
func (fss *StreamingService) ListenDeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) (rerr error) {
|
||||
// generate the new file
|
||||
dstFile, err := fss.openDeliverTxFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
cerr := dstFile.Close()
|
||||
if rerr == nil {
|
||||
rerr = cerr
|
||||
}
|
||||
}()
|
||||
|
||||
// write req to file
|
||||
lengthPrefixedReqBytes, err := fss.codec.MarshalLengthPrefixed(&req)
|
||||
if err != nil {
|
||||
@ -170,11 +181,8 @@ func (fss *StreamingService) ListenDeliverTx(ctx sdk.Context, req abci.RequestDe
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = dstFile.Write(lengthPrefixedResBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
// close file
|
||||
return dstFile.Close()
|
||||
_, err = dstFile.Write(lengthPrefixedResBytes)
|
||||
return err
|
||||
}
|
||||
|
||||
func (fss *StreamingService) openDeliverTxFile() (*os.File, error) {
|
||||
@ -189,12 +197,19 @@ func (fss *StreamingService) openDeliverTxFile() (*os.File, error) {
|
||||
// ListenEndBlock satisfies the baseapp.ABCIListener interface
|
||||
// It writes the received EndBlock request and response and the resulting state changes
|
||||
// out to a file as described in the above the naming schema
|
||||
func (fss *StreamingService) ListenEndBlock(ctx sdk.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error {
|
||||
func (fss *StreamingService) ListenEndBlock(ctx sdk.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) (rerr error) {
|
||||
// generate the new file
|
||||
dstFile, err := fss.openEndBlockFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
cerr := dstFile.Close()
|
||||
if rerr == nil {
|
||||
rerr = cerr
|
||||
}
|
||||
}()
|
||||
|
||||
// write req to file
|
||||
lengthPrefixedReqBytes, err := fss.codec.MarshalLengthPrefixed(&req)
|
||||
if err != nil {
|
||||
@ -220,11 +235,8 @@ func (fss *StreamingService) ListenEndBlock(ctx sdk.Context, req abci.RequestEnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = dstFile.Write(lengthPrefixedResBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
// close file
|
||||
return dstFile.Close()
|
||||
_, err = dstFile.Write(lengthPrefixedResBytes)
|
||||
return err
|
||||
}
|
||||
|
||||
func (fss *StreamingService) openEndBlockFile() (*os.File, error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user