|
4 | 4 | "fmt" |
5 | 5 | "path" |
6 | 6 | "strconv" |
| 7 | + "strings" |
7 | 8 | "time" |
8 | 9 |
|
9 | 10 | "github.com/v3io/v3io-go/pkg/dataplane" |
@@ -104,12 +105,33 @@ func (c *claim) fetchRecordBatches(stopChannel chan struct{}, fetchInterval time |
104 | 105 | for { |
105 | 106 | select { |
106 | 107 | case <-time.After(fetchInterval): |
107 | | - c.currentShardLocation, err = c.fetchRecordBatch(c.currentShardLocation) |
| 108 | + location, err := c.fetchRecordBatch(c.currentShardLocation) |
108 | 109 | if err != nil { |
109 | | - c.logger.WarnWith("Failed fetching record batch", "err", errors.GetErrorStackString(err, 10)) |
| 110 | + c.logger.WarnWith("Failed fetching record batch", |
| 111 | + "shardId", c.shardID, |
| 112 | + "err", errors.GetErrorStackString(err, 10)) |
| 113 | + |
| 114 | + // if the error is that the location we asked for is bad, try to seek earliest |
| 115 | + if c.checkIllegalLocationErr(err) { |
| 116 | + location, err := c.recoverLocationAfterIllegalLocationErr() |
| 117 | + |
| 118 | + if err != nil { |
| 119 | + c.logger.WarnWith("Failed to recover after illegal location", |
| 120 | + "shardId", c.shardID, |
| 121 | + "err", errors.GetErrorStackString(err, 10)) |
| 122 | + |
| 123 | + continue |
| 124 | + } |
| 125 | + |
| 126 | + // set next location for next time |
| 127 | + c.currentShardLocation = location |
| 128 | + } |
| 129 | + |
110 | 130 | continue |
111 | 131 | } |
112 | 132 |
|
| 133 | + c.currentShardLocation = location |
| 134 | + |
113 | 135 | case <-stopChannel: |
114 | 136 | close(c.recordBatchChan) |
115 | 137 | c.logger.Debug("Stopping fetch") |
@@ -202,3 +224,47 @@ func (c *claim) getCurrentShardLocation(shardID int) (string, error) { |
202 | 224 |
|
203 | 225 | return currentShardLocation, nil |
204 | 226 | } |
| 227 | + |
| 228 | +func (c *claim) checkIllegalLocationErr(err error) bool { |
| 229 | + |
| 230 | + // sanity |
| 231 | + if err == nil { |
| 232 | + return false |
| 233 | + } |
| 234 | + |
| 235 | + // try to get the cause |
| 236 | + causeErr := errors.Cause(err) |
| 237 | + if causeErr == nil { |
| 238 | + |
| 239 | + // if we can't determind the cause, don't assume location (sanity) |
| 240 | + return false |
| 241 | + } |
| 242 | + |
| 243 | + return strings.Contains(causeErr.Error(), "IllegalLocationException") |
| 244 | +} |
| 245 | + |
| 246 | +func (c *claim) recoverLocationAfterIllegalLocationErr() (string, error) { |
| 247 | + c.logger.InfoWith("Location requested is invalid. Trying to seek to earliest", |
| 248 | + "shardId", c.shardID, |
| 249 | + "location", c.currentShardLocation) |
| 250 | + |
| 251 | + streamPath, err := c.member.streamConsumerGroup.getShardPath(c.shardID) |
| 252 | + if err != nil { |
| 253 | + return "", errors.Wrap(err, "Failed to get shard path") |
| 254 | + } |
| 255 | + |
| 256 | + location, err := c.member.streamConsumerGroup.getShardLocationWithSeek(&v3io.SeekShardInput{ |
| 257 | + Path: streamPath, |
| 258 | + Type: v3io.SeekShardInputTypeEarliest, |
| 259 | + }) |
| 260 | + |
| 261 | + if err != nil { |
| 262 | + return "", errors.Wrap(err, "Failed to seek to earliest") |
| 263 | + } |
| 264 | + |
| 265 | + c.logger.InfoWith("Got new location after seeking to earliest", |
| 266 | + "shardId", c.shardID, |
| 267 | + "location", location) |
| 268 | + |
| 269 | + return location, nil |
| 270 | +} |
0 commit comments