helix-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kishore g <g.kish...@gmail.com>
Subject Re: Helix 0.6.2 State Machine Question
Date Wed, 19 Feb 2014 17:59:55 GMT
Makes sense, thanks a lot for these inputs. Feel free to make the changes
and submit reviews. Let us know if the process to submit patch is hard.
Using github to submit patches might be easier.


On Wed, Feb 19, 2014 at 8:43 AM, Sandeep Nayak <osgigeek@gmail.com> wrote:

> Ah, I see. Thanks for the response, I will make the necessary changes.
>
> Ideally the builder does not allow the user to define those two states (or
> they are upper-case it internally before we add to the state machine), and
> have the transitions validated so that there are valid transitions to those
> states.
>
>
> On Wed, Feb 19, 2014 at 7:29 AM, kishore g <g.kishore@gmail.com> wrote:
>
>> Dropped is a special Helix defined state. It needs to be called
>> DROPPED(case sensistive). ERROR and DROPPED are the two states that are
>> defined by Helix and must be defined as part of every state machine.
>> Changing you Dropped to DROPPED should fix it. We can probably relax it to
>> be case insensitive.
>>
>> public enum HelixDefinedState {
>>   ERROR,
>>   DROPPED
>> }
>>
>> We should probably have this enums part of State class.
>>
>>
>>
>>
>> On Wed, Feb 19, 2014 at 7:22 AM, Sandeep Nayak <osgigeek@gmail.com>wrote:
>>
>>> Hi Kishore,
>>>
>>> The NodeState is an enum, and yes I pretty much started with the
>>> Quickstart.java to get something working.
>>>
>>> private enum NodeState{
>>>
>>>     LEADER("Leader"),
>>>
>>>     FOLLOWER("Follower"),
>>>
>>>     OFFLINE("Offline"),
>>>
>>>     DROPPED("Dropped");
>>>
>>>     private String name;
>>>
>>>     private NodeState(String name){
>>>
>>>       this.name = name;
>>>
>>>     }
>>>
>>>     public String label(){
>>>
>>>       return this.name;
>>>
>>>     }
>>>
>>> Thanks,
>>>
>>> Sandeep
>>>
>>>
>>> On Tue, Feb 18, 2014 at 11:28 PM, kishore g <g.kishore@gmail.com> wrote:
>>>
>>>> Can you paste the NodeState class. Quickstart has pretty much the same
>>>> code and that works. The only difference in your case are the names LEADER
>>>> --> MASTER, FOLLOWER --> SLAVE.
>>>>
>>>>
>>>>     StateModelDefinition.Builder builder = new
>>>> StateModelDefinition.Builder(STATE_MODEL_NAME);
>>>>     // Add states and their rank to indicate priority. Lower the rank
>>>> higher the
>>>>     // priority
>>>>     builder.addState(MASTER, 1);
>>>>     builder.addState(SLAVE, 2);
>>>>     builder.addState(OFFLINE);
>>>>     builder.addState(DROPPED);
>>>>     // Set the initial state when the node starts
>>>>     builder.initialState(OFFLINE);
>>>>
>>>>     // Add transitions between the states.
>>>>     builder.addTransition(OFFLINE, SLAVE);
>>>>     builder.addTransition(SLAVE, OFFLINE);
>>>>     builder.addTransition(SLAVE, MASTER);
>>>>     builder.addTransition(MASTER, SLAVE);
>>>>     builder.addTransition(OFFLINE, DROPPED);
>>>>
>>>>     // set constraints on states.
>>>>     // static constraint
>>>>     builder.upperBound(MASTER, 1);
>>>>     // dynamic constraint, R means it should be derived based on the
>>>> replication
>>>>     // factor.
>>>>     builder.dynamicUpperBound(SLAVE, "R");
>>>>
>>>>
>>>> On Tue, Feb 18, 2014 at 10:55 PM, Sandeep Nayak <osgigeek@gmail.com>wrote:
>>>>
>>>>> Hi guys,
>>>>>
>>>>> I have the following states for my instances
>>>>>
>>>>> StateModelDefinition.Builder builder = newStateModelDefinition.Builder(
>>>>> NODE_STATE_MODEL);
>>>>>
>>>>> builder.initialState(NodeState.OFFLINE.label());
>>>>>
>>>>> builder.addState(NodeState.LEADER.label(), 1);
>>>>>
>>>>> builder.addState(NodeState.FOLLOWER.label(), 2);
>>>>>
>>>>> builder.addState(NodeState.OFFLINE.label());
>>>>>
>>>>> builder.addState(NodeState.DROPPED.label());
>>>>>
>>>>> //State transitions
>>>>>
>>>>> builder.addTransition(NodeState.OFFLINE.label(),NodeState.FOLLOWER
>>>>> .label());
>>>>>
>>>>> builder.addTransition(NodeState.FOLLOWER.label(),NodeState.OFFLINE
>>>>> .label());
>>>>>
>>>>> builder.addTransition(NodeState.FOLLOWER.label(), NodeState.LEADER
>>>>> .label());
>>>>>
>>>>> builder.addTransition(NodeState.LEADER.label(), NodeState.FOLLOWER
>>>>> .label());
>>>>>
>>>>> builder.addTransition(NodeState.OFFLINE.label(), NodeState.DROPPED
>>>>> .label());
>>>>>
>>>>> builder.upperBound(NodeState.LEADER.label(), 1);
>>>>>
>>>>> builder.dynamicUpperBound(NodeState.FOLLOWER.label(), "R");
>>>>>
>>>>> stateModelDefinition = builder.build();
>>>>>
>>>>>     if(admin.getStateModelDef(clusterName, stateModelDefinition.getId())
>>>>> == null){
>>>>>
>>>>>       admin.addStateModelDef(clusterName, NODE_STATE_MODEL,
>>>>> stateModelDefinition);
>>>>>
>>>>>     }
>>>>>
>>>>>
>>>>> The addStateModelDef fails with the following exception
>>>>>
>>>>> ERROR org.apache.helix.model.util.StateModelDefinitionValidator  -
>>>>> Defined states does not include the DROPPED state, state model:
>>>>> Node-State-Model
>>>>>
>>>>> org.apache.helix.HelixException: The ZNRecord for STATEMODELDEFS is
>>>>> not valid.
>>>>>
>>>>> at org.apache.helix.manager.zk.ZKHelixDataAccessor.setProperty(
>>>>> ZKHelixDataAccessor.java:97)
>>>>>
>>>>>  at org.apache.helix.manager.zk.ZKHelixAdmin.addStateModelDef(
>>>>> ZKHelixAdmin.java:698)
>>>>>
>>>>>
>>>>> Any idea what I am doing wrong?
>>>>>
>>>>> On a separate note a few things to note
>>>>>
>>>>> (1) we should have symmetry on the APIs, the getStateModelDef does
>>>>> return null and does not throw an exception like the getInstanceConfig
if
>>>>> it does not find the state model def.
>>>>>
>>>>> (2) Should the validation happen in the builder? So that it fails
>>>>> early?
>>>>>
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Sandeep
>>>>>
>>>>
>>>>
>>>
>>
>

Mime
View raw message