/* * Copyright 2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package io.atomix.group.internal; import io.atomix.copycat.server.Commit; import io.atomix.copycat.server.session.ServerSession; import io.atomix.group.messaging.internal.GroupMessage; import java.util.LinkedHashMap; import java.util.Map; /** * Group member state. * * @author <a href="http://github.com/kuujo>Jordan Halterman</a> */ final class MemberState implements AutoCloseable { private final Commit<GroupCommands.Join> commit; private final long index; private final String memberId; private final boolean persistent; private ServerSession session; private Object metadata; private final Map<Long, MessageState> messages = new LinkedHashMap<>(); MemberState(Commit<GroupCommands.Join> commit) { this.commit = commit; this.index = commit.index(); this.memberId = commit.operation().member(); this.persistent = commit.operation().persist(); this.session = commit.session(); this.metadata = commit.operation().metadata(); } /** * Returns the member index. */ public long index() { return index; } /** * Returns the member ID. */ public String id() { return memberId; } /** * Returns group member info. */ public GroupMemberInfo info() { return new GroupMemberInfo(index, memberId, metadata); } /** * Returns the member session. */ public ServerSession session() { return session; } /** * Sets the member session. */ public void setSession(ServerSession session) { this.session = session; if (session != null && session.state().active()) { for (MessageState message : messages.values()) { session.publish("message", new GroupMessage<>(message.index(), memberId, message.queue(), message.message())); } } } /** * Returns a boolean indicating whether the member is persistent. */ public boolean persistent() { return persistent; } public Object metadata() { return metadata; } /** * Submits the given message to be processed by the member. */ public void submit(MessageState message) { messages.put(message.index(), message); if (session != null && session.state().active()) { session.publish("message", new GroupMessage<>(message.index(), memberId, message.queue(), message.message())); } } /** * Replies to the message. */ public void reply(MessageState message, GroupCommands.Reply reply) { messages.remove(message.index()); message.reply(reply); } @Override public void close() { messages.values().forEach(MessageState::expire); commit.close(); } @Override public int hashCode() { return commit.hashCode(); } @Override public boolean equals(Object object) { return object instanceof MemberState && ((MemberState) object).id().equals(id()); } }