Announcement

Collapse
No announcement yet.

Why voltdb::Client constructor is private

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why voltdb::Client constructor is private

    Hi,
    I wonder why voltdb::Client's constructor was designed as a private method, so that mean the Class could only be instantiated by static method Client::create, right? This bring me a question:

    if I want to design a class such as:

    class FOO {
    voltdb::Client client; // compiler error: private constructor method. Even declare client as pointer or reference type,
    // the temp obj returned by create(config) will released at the end of constructor FOO()
    voltdb::Procedure *proc; // compiler error: no Procedure() method.

    FOO(string name, string passwd, string hostaddr) {
    ...
    client = voltdb::Client::create(config);
    ...
    proc = new voltdb::Procedure("xxx", param);
    }
    bool callTheProc(int p1, int p2, int p3) {
    ......
    client.invoke(proc);
    ......
    }

    ~foo() { do some delete things }
    ......
    };

    when I use FOO in other place just like:

    somefunc() {
    FOO foo("", "", "localhost"); // failed
    ......
    for(.......)
    {
    p1=fun1();p2=fun2();p3=fun3();
    foo.callTheProc(p1, p2, p3);
    }
    ......
    }

    With the question I mentioned, all codes should be coded in somefunc() body just like the demo program did(Helloworld), it's really not a good way.
    I don't know how could I design a class with voltdb connecting and bulk data assessing in deferent methods. Not sure if I describe my question clearly.
    Thanks a lot!

  • #2
    Hi. This is Bill White of VoltDB.

    The implementation of the Client object involves many types and parameters from which we wish to shield the application. They are not actually secret, in the sense that people can't know them. The client is open source, so you can see everything by inspecting the source code. We are trying to keep the application from depending on definitions used in the Client but not directly in the application.

    The Client object is very lightweight. If you look at the code you see that it only has a reference counted pointer. This is a kind of pattern called the PIMPL pattern, or Private Implementation pattern. It's used to separate private implementation details from public interfaces. If you look at the class ClientImpl you will see the actual client implementation. You can only use the ClientImpl through the Client interface, though.

    You can store a client in your FOO class, and construct FOO with a ClientConfiguration object something like this:


    class FOO {
    Client m_client;
    public:
    FOO(ClientConfig *config)
    : m_client(Client::create(config)) {}

    bool callTheProc(int p1, int p2, int p2) {
    client.invoke(proc);
    }

    ... The rest of the class.
    };

    main()
    {
    ClientConfig config("name", "password");
    FOO fooInstance(&config);
    if (fooInstance.callTheProc(100, 101, 102)) {
    std::cout << "Hooray for us!!" << std::endl;
    }
    }

    Does this make sense? The member variable m_client is not initialized until the constructor. The default copy constructor works here, as we just transfer a reference. This should be quite fast.

    I haven't actually tried this out, so I may not be 100% correct in the syntax of my example. I'm going to create a more complete example. I'll let you know what I come up with. But I fear it won't be today.


    Comment


    • #3
      Cool, Bill! why I didn't try using constructor in this way?! It works. Thank you very much.

      Comment

      Working...
      X