Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

store/tikv: refactor copIterator #2804

Merged
merged 17 commits into from
Mar 15, 2017
Merged

Conversation

tiancaiamao
Copy link
Contributor

make the code simpler, so it's easy to reason about:

  • change tasks' struct from array to list, which benefit for rebuildCurrentTask
  • remove the complex lock related code
  • fix memory leak

PTAL @coocood @disksing @shenli @zimulala

make the code simpler, so it's easy to reason about:
* change tasks' struct from array to list, which benefit for rebuildCurrentTask
* remove the complex lock related code
* fix memory leak
}
}
}

func (it *copIterator) run(ctx goctx.Context) {
for t := it.tasks; t != nil; t = t.next {
it.addTask(t)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

task channel may be full, blocked forever.

@disksing disksing changed the title store/tikv: refact copIterator store/tikv: refactor copIterator Mar 10, 2017
it.mu.tasks[i].idx = i
}
// This is simple, just replace the old task node with the new task list.
replaceNodeWithList(task, newTasks)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new tasks could be processed by other workers before be inserted to list.

// The worker function that get a copTask from channel, handle it and
// send the result back.
func (it *copIterator) work(ctx goctx.Context, taskCh <-chan *copTask) {
for task := range taskCh {
bo := NewBackoffer(copNextMaxBackoff, ctx)
startTime := time.Now()
resp, err := it.handleTask(bo, task)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about handleTask returns multiple responses, then we can make sure the new tasks is handled immediately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! I'll have a try.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The multiple responses can be sent to the original task's channel.

Instead of just read one response, the reader reads multiple responses from a task's channel until the channel is closed.

Then we don't need a task list because the original tasks never change.

@tiancaiamao tiancaiamao force-pushed the tiancaiamao/refact-copiterator branch from d48f1c1 to 5244954 Compare March 13, 2017 06:04
@tiancaiamao
Copy link
Contributor Author

@coocood @disksing PTAL
Now handleTask returns a slice of Response, so split task is not need any more, which make the logic greatly simplified.

it.mu.Lock()
task.status = taskDone
it.mu.Unlock()
it.curr++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only read 1 response from each task?

@coocood
Copy link
Member

coocood commented Mar 13, 2017

Looks much better.
Now, we need to add tests for multiple region MockTiKV cluster, and split region during execution.

@coocood
Copy link
Member

coocood commented Mar 14, 2017

LGTM

@tiancaiamao tiancaiamao force-pushed the tiancaiamao/refact-copiterator branch from 9e36404 to 7c104f1 Compare March 14, 2017 09:38
@tiancaiamao
Copy link
Contributor Author

PTAL @disksing

finished chan struct{}
taskCh chan *copTask

// If keepOrder, result is stored in copTask.respChan, read them out one by one.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/result is/results are/

@tiancaiamao tiancaiamao force-pushed the tiancaiamao/refact-copiterator branch from 99cc756 to 7c7fdb2 Compare March 15, 2017 02:56
// Rebuild current task. It may be split into multiple tasks (in region split scenario).
func (it *copIterator) rebuildCurrentTask(bo *Backoffer, task *copTask) error {
// Rebuild and handle current task. It may be split into multiple tasks (in region split scenario).
func (it *copIterator) rebuildCurrentTask(bo *Backoffer, task *copTask) []copResponse {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pick a better name for this function. How about handleRegionErrorTask?

@disksing
Copy link
Contributor

LGTM

@coocood coocood merged commit 88d8a84 into master Mar 15, 2017
@coocood coocood deleted the tiancaiamao/refact-copiterator branch March 15, 2017 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants