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

feat(method): support method in definition #211

Merged
merged 2 commits into from Jun 20, 2018

Conversation

kdada
Copy link
Collaborator

@kdada kdada commented Jun 6, 2018

What this PR does / why we need it:

In the past, definition.Function only support functions. With method package in this pr, you can get the power to make a method be like a function.

// Before nirvana server starting
instance := InitSomeClass()
method.Put(instance)

// In definition:
{
    ...
    Function: method.Get(&SomeClass{}, "SomeMethod"),
    ... 
}

Then you don't need to do this:

func (* SomeClass) Definitions()[]definition.Definition {
    return []definition.Definition {
        ...
        Function: this.SomeMethod,
        ... 
    }
}

Which issue(s) this PR is related to (optional, link to 3rd issue(s)):

Fixes #

Reference to #

Special notes for your reviewer:

/cc @ddysher

Release note:

NONE

@caicloud-bot caicloud-bot requested a review from ddysher June 6, 2018 02:20
@caicloud-bot caicloud-bot added release-note-none Denotes a PR that doesn't merit a release note. caicloud-cla: yes Indicates the PR's author has not signed the Caicloud CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jun 6, 2018
@ddysher
Copy link
Member

ddysher commented Jun 13, 2018

@kdada few comments:

  • we are constructing a struct instance when registering the function method, what is the implication behind this, i.e.
    • what if user wants to instantiate the struct with field value, e.g. Function: method.Get(&SomeClass{Some: 'abc'}, "SomeMethod"),, is this a valid use case?
    • what happens to the object (&SomeClass{}) after registration?
    • what if user wants to create another instance, do we want them to reuse the object?
  • you seems to use MakeFunction to wrap the registered function, what is the performance penalty?

It's common to register multiple methods of a class, in current setup, users are supposed to do this multiple times, each time with a new instance of the object?

{
    ...
    Function: method.Get(&SomeClass{}, "SomeMethod1"),
    Function: method.Get(&SomeClass{}, "SomeMethod2"),
    Function: method.Get(&SomeClass{}, "SomeMethod2"),
    ... 
}

@ddysher
Copy link
Member

ddysher commented Jun 13, 2018

👆 @kdada can u provide some pprof results (esp. memory for objects)? that will make me feel better ...

@kdada
Copy link
Collaborator Author

kdada commented Jun 13, 2018

@ddysher

The method package provides a pattern to Get and Put instances.

Get returns a lazy loaded function. The function has a certain function prototype and an indefinite execution body. Related instance of the function won't be set until someone calls the function. This mechanism ensure that we can separate API definitions and instances.
The first parameter of Get is only for extracting instance type. So a filled object makes no sense.

Put is simple. The method just put an instance into method container. But for a type, there is only one instance valid. That means if you Put many instances with same type, only the last one is used.

Benchmark:

BenchmarkContainer-8     3000000               406 ns/op
BenchmarkDirect-8       10000000               222 ns/op

Function warp has twice consumption than direct call. But it isn't a big deal. Because the overhead of an entire API request is in microsecond. (PS. I'll write an unsafe calling package to skip the safe check of reflect packge. )

func (t *TestStruct) Number() int {
return t.a
}

Copy link
Contributor

@zjj2wry zjj2wry Jun 20, 2018

Choose a reason for hiding this comment

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

add another struct implement TestInterface,used for test putInterface.

func (t *Test2Struct) Number() int {
	return t.a*2
}

func TestContainer(t *testing.T) {
cases := []struct {
typ interface{}
instance interface{}
Copy link
Contributor

@zjj2wry zjj2wry Jun 20, 2018

Choose a reason for hiding this comment

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

func NewTest(number int) TestInterface{
    return &TestStruct{
                  a: number, 
               }
}

Usually the initialization instance is a factory, and the instance can use the following method?

@zjj2wry
Copy link
Contributor

zjj2wry commented Jun 20, 2018

/lgtm

@caicloud-bot caicloud-bot added the lgtm Indicates that a PR is ready to be merged. label Jun 20, 2018
@kdada
Copy link
Collaborator Author

kdada commented Jun 20, 2018

/approve

@caicloud-bot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kdada, zjj2wry

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@caicloud-bot caicloud-bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 20, 2018
@caicloud-bot caicloud-bot merged commit d221eab into caicloud:master Jun 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. caicloud-cla: yes Indicates the PR's author has not signed the Caicloud CLA. lgtm Indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants