Update object
(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption)
| 107 | |
| 108 | // Update object |
| 109 | func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) error { |
| 110 | realpath := o.fs.realpath(o.remote) |
| 111 | dirname := path.Dir(realpath) |
| 112 | fs.Debugf(o.fs, "update [%s]", realpath) |
| 113 | |
| 114 | err := o.fs.client.MkdirAll(dirname, 0755) |
| 115 | if err != nil { |
| 116 | return err |
| 117 | } |
| 118 | |
| 119 | _, err = o.fs.client.Stat(realpath) |
| 120 | if err == nil { |
| 121 | err = o.fs.client.Remove(realpath) |
| 122 | if err != nil { |
| 123 | return err |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | out, err := o.fs.client.Create(realpath) |
| 128 | if err != nil { |
| 129 | return err |
| 130 | } |
| 131 | |
| 132 | cleanup := func() { |
| 133 | rerr := o.fs.client.Remove(realpath) |
| 134 | if rerr != nil { |
| 135 | fs.Errorf(o.fs, "failed to remove [%v]: %v", realpath, rerr) |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | _, err = io.Copy(out, in) |
| 140 | if err != nil { |
| 141 | cleanup() |
| 142 | return err |
| 143 | } |
| 144 | |
| 145 | // If the datanodes have acknowledged all writes but not yet |
| 146 | // to the namenode, FileWriter.Close can return ErrReplicating |
| 147 | // (wrapped in an os.PathError). This indicates that all data |
| 148 | // has been written, but the lease is still open for the file. |
| 149 | // |
| 150 | // It is safe in this case to either ignore the error (and let |
| 151 | // the lease expire on its own) or to call Close multiple |
| 152 | // times until it completes without an error. The Java client, |
| 153 | // for context, always chooses to retry, with exponential |
| 154 | // backoff. |
| 155 | err = o.fs.pacer.Call(func() (bool, error) { |
| 156 | err := out.Close() |
| 157 | if err == nil { |
| 158 | return false, nil |
| 159 | } |
| 160 | return errors.Is(err, hdfs.ErrReplicating), err |
| 161 | }) |
| 162 | if err != nil { |
| 163 | cleanup() |
| 164 | return err |
| 165 | } |
| 166 |