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

*: Add the mock owner-manager and schema-syncer #3359

Merged
merged 17 commits into from Jun 4, 2017

Conversation

zimulala
Copy link
Contributor

@zimulala zimulala commented May 30, 2017

This PR add the interface of owner-manager and schema-syncer. Besides mocks owner-manager and schema-syncer. We use these interfaces instead of the old way.
The next PR I will remove the old code and add some tests.

// CampaignOwners campaigns the DDL owner and the background owner.
CampaignOwners(ctx goctx.Context, wg *sync.WaitGroup) error

SchemaSyncer
Copy link
Member

Choose a reason for hiding this comment

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

Move this to the beginning of the interface.

// ChangeOwnerInNewWay is used for testing.
var ChangeOwnerInNewWay = false
// EtcdWorker is an interface for DDL access the etcd.
type EtcdWorker interface {
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 rename it to DDLSyncer.
DDL workers use DDLSyncer to synchronize ddl information. Using etcd to synchronize ddl information is an implementation of DDLSyncer. So put etcd in the name of the interface is not proper.

Copy link
Contributor

Choose a reason for hiding this comment

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

It also used to elect ddl leader, so Syncer is not accuracy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it's also used to campaign the owners. So DDLSyncer may not be good.


// mockEtcdWorker represents the structure which is used for electing owner.
// It's used for local store and testing.
// So this worker always the ddl owner and background owner.
Copy link
Member

Choose a reason for hiding this comment

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

How to test the scenario with multiple ddl workers?

Copy link
Contributor

Choose a reason for hiding this comment

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

Integration testing, I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have the DDL integration tests to test the multiple DDL workers.
The original test is only one is measured this situation. And Do we need to mock a object to mock this test?

@shenli
Copy link
Member

shenli commented May 30, 2017

@tiancaiamao PTAL

@zimulala zimulala added the Priority/P1 Features that will be implemented in the latest or next major/minor version label May 31, 2017
ddl/ddl.go Outdated
@@ -163,8 +163,8 @@ type ddl struct {
hook Callback
hookMu sync.RWMutex
store kv.Storage
// worker is used for electing the owner.
worker *worker
// worker is used for DDL access the etcd.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/access/to access

ddl/ddl.go Outdated
@@ -320,7 +319,7 @@ func (d *ddl) close() {
}

close(d.quitCh)
d.worker.cancel()
d.worker.Cancel()
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer NewEtcdWorker with d.quitCh, so when close(d.quitCh), the etcd worker will get notification too.

defer d2.Stop()

// Change the DDL owner.
d1.Stop()
Copy link
Contributor

Choose a reason for hiding this comment

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

why remove those code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because the mock etcd worker is the local store, this worker must be the owner.

// ChangeOwnerInNewWay is used for testing.
var ChangeOwnerInNewWay = false
// EtcdWorker is an interface for DDL access the etcd.
type EtcdWorker interface {
Copy link
Contributor

Choose a reason for hiding this comment

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

It also used to elect ddl leader, so Syncer is not accuracy.

SchemaSyncer

// Cancel cancels this etcd worker campaign.
Cancel()
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't need this, really...

Copy link
Contributor

Choose a reason for hiding this comment

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

cancel and close is not the same thing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, so I cancel the campaign operation.

Copy link
Contributor

Choose a reason for hiding this comment

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

So, can this function be called multiple times?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This question we discussed.

func (d *ddl) campaignOwners(ctx goctx.Context) error {
err := d.worker.newSession(ctx, newSessionDefaultRetryCnt)
// CampaignOwners implements EtcdWorker.CampaignOwners interface.
func (w *worker) CampaignOwners(ctx goctx.Context, wg *sync.WaitGroup) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

why wg not a member of worker, but pass as argument instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It uses the DDL's wg.


// mockEtcdWorker represents the structure which is used for electing owner.
// It's used for local store and testing.
// So this worker always the ddl owner and background owner.
Copy link
Contributor

Choose a reason for hiding this comment

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

Integration testing, I guess.

}

// Init implements SchemaSyncer.Init interface.
func (s *mockSchemaSyncer) Init(ctx goctx.Context) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

You can mock a SchemaSyncer, without etcd client.

m, err := d.Stats()
c.Assert(err, IsNil)
c.Assert(m[ddlOwnerID], Equals, d.uuid)
// TODO: Get this information from etcd.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it changed in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not yet. It will do at the next PR.

@zimulala
Copy link
Contributor Author

PTAL @tiancaiamao @coocood @shenli

for {
select {
case <-worker.etcdSession.Done():
case <-w.etcdSession.Done():
// TODO: Create session again?
Copy link
Member

Choose a reason for hiding this comment

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

Should we fix this TODO before rc3

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shenli
I added it in this PR.

worker.watchOwner(ctx, string(resp.Kvs[0].Key))
worker.setOwnerVal(key, false)
d.hookMu.Lock()
d.hook.OnWatched(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

Why remove this hook?

@@ -216,21 +216,19 @@ func (s *testSchemaSuite) TestSchemaWaitJob(c *C) {
ctx := testNewContext(d2)

// d2 must not be owner.
testCheckOwner(c, d2, false, ddlJobFlag)
d2.worker.SetOwner(false)
Copy link
Member

Choose a reason for hiding this comment

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

Should we check if d2.worker.IsOwner()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was checked in line227.


schemaID, err := d2.genGlobalID()
c.Assert(err, IsNil)
doDDLJobErr(c, schemaID, 0, model.ActionCreateSchema, []interface{}{dbInfo}, ctx, d2)

// d2 must not be owner.
testCheckOwner(c, d2, false, ddlJobFlag)
Copy link
Member

Choose a reason for hiding this comment

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

Should we check this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

d2 uses a mock worker,it only changes the owner state by us,so I don't think it's necessary to check.

@shenli
Copy link
Member

shenli commented May 31, 2017

@tiancaiamao @coocood PTAL

// ChangeOwnerInNewWay is used for testing.
var ChangeOwnerInNewWay = false
// EtcdWorker is an interface for DDL to access the etcd.
type EtcdWorker interface {
Copy link
Member

Choose a reason for hiding this comment

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

Since it is an interface, it doesn't have to be etcd, etcd it's the implementation.

I think separate it into two interfaces is better.
One is SchemaSyncer, the other one is OwnerManager.

@zimulala zimulala added this to the rc3 milestone Jun 1, 2017
ddl/ddl.go Outdated
// If etcdCli is nil, it's the local store, so use the mockOwnerManager and mockSchemaSyncer.
// It's always used for testing.
if etcdCli == nil {
manager = NewMockOwnerManager(etcdCli, id, cancelFunc)
Copy link
Member

Choose a reason for hiding this comment

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

Why pass nil etcdCli to create mock manager and mock sycner?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because if it's the local store, domain's etcdCli is nil. It's original logic.

ddl/mock.go Outdated
}

// NewMockOwnerManager creates a new mock OwnerManager.
func NewMockOwnerManager(etcdCli *clientv3.Client, id string, cancel goctx.CancelFunc) OwnerManager {
Copy link
Member

Choose a reason for hiding this comment

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

The first argument is not used.

ddl/mock.go Outdated
// See the License for the specific language governing permissions and
// limitations under the License.

// Package ddl is just for test only.
Copy link
Member

Choose a reason for hiding this comment

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

This comment confuses me.

ddl/mock.go Outdated

// mockOwnerManager represents the structure which is used for electing owner.
// It's used for local store and testing.
// So this worker always the ddl owner and background owner.
Copy link
Member

Choose a reason for hiding this comment

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

will always be

ddl/mock.go Outdated
}

// CampaignOwners implements mockOwnerManager.CampaignOwners interface.
func (m *mockOwnerManager) CampaignOwners(_ goctx.Context, _ *sync.WaitGroup) error { return nil }
Copy link
Member

Choose a reason for hiding this comment

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

Need to set m.ddlOwner to 1?


// ChangeOwnerInNewWay is used for controlling the way of changing owner.
// TODO: Remove it.
var ChangeOwnerInNewWay = true
Copy link
Member

Choose a reason for hiding this comment

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

Seems this is never used.

@zimulala
Copy link
Contributor Author

zimulala commented Jun 2, 2017

PTAL @shenli @coocood @tiancaiamao

@coocood
Copy link
Member

coocood commented Jun 2, 2017

LGTM

@zimulala zimulala added the DNM label Jun 2, 2017
ddl/mock.go Outdated

// OwnerCheckAllVersions implements SchemaSyncer.OwnerCheckAllVersions interface.
func (s *mockSchemaSyncer) OwnerCheckAllVersions(ctx goctx.Context, latestVer int64) error {
for {
Copy link
Contributor

Choose a reason for hiding this comment

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

ticker := time.NewTicker(mockCheckVersInterval)
defer ticker.Close()
select {
    case <-ctx.Done():
    case <-ticker.C:
         ver := atomic.LoadInt64(&s.selfSchemaVersion)
 	 if ver == latestVer {
 		return nil
 	 }
}

ddl/syncer.go Outdated
return s.globalVerCh
}

// UpdateSelfVersion implements SchemaSyncer.UpdateSelfVersion interface.
func (s *schemaVersionSyncer) UpdateSelfVersion(ctx goctx.Context, version int64) error {
ver := strconv.FormatInt(version, 10)
return s.putKV(ctx, putKeyNoRetry, s.selfSchemaVerPath, ver)
Copy link
Contributor

Choose a reason for hiding this comment

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

It should put with a lease option, so if RemoveSelfVersionPath fail, the path will be remove automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This will do for the next PR.

@zimulala
Copy link
Contributor Author

zimulala commented Jun 2, 2017

PTAL @shenli @tiancaiamao

@zimulala zimulala removed the DNM label Jun 2, 2017
@zimulala zimulala changed the title *: Add the mock etcd worker *: Add the mock owner-manager and schema-syncer Jun 2, 2017
@shenli
Copy link
Member

shenli commented Jun 2, 2017

LGTM

@zimulala zimulala added the DNM label Jun 2, 2017
@shenli shenli merged commit 62450b9 into master Jun 4, 2017
@shenli shenli deleted the zimuxia/mock-etcd-worker branch June 5, 2017 06:50
@shenli shenli removed the DNM label Jun 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority/P1 Features that will be implemented in the latest or next major/minor version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants