protected BlockingCollection <List <IMessage> > subscribeInternal(string host, int port, string tableName, string actionName, MessageHandler handler, long offset, bool reconnect, IVector filter, bool createSubInfo) { string topic = ""; IEntity re; BlockingCollection <List <IMessage> > queue; DBConnection dbConn = new DBConnection(); dbConn.connect(host, port); try { string localIP = listeningHost_; if (localIP == null || localIP.Equals(String.Empty)) { localIP = dbConn.LocalAddress; } List <IEntity> @params = new List <IEntity> { new BasicString(tableName), new BasicString(actionName) }; re = dbConn.run("getSubscriptionTopic", @params); topic = ((BasicAnyVector)re).getEntity(0).getString(); @params.Clear(); @params.Add(new BasicString(localIP)); @params.Add(new BasicInt(listeningPort_)); @params.Add(new BasicString(tableName)); @params.Add(new BasicString(actionName)); @params.Add(new BasicLong(offset)); if (filter != null) { @params.Add(filter); } re = dbConn.run("publishTable", @params); lock (subscribeInfos_) { if (createSubInfo) { Site[] sites; if (re is BasicAnyVector) { BasicStringVector HASiteStrings = (BasicStringVector)((BasicAnyVector)re).getEntity(1); int HASiteNum = HASiteStrings.rows(); sites = new Site[HASiteNum]; for (int i = 0; i < HASiteNum; ++i) { String HASite = HASiteStrings.get(i).getString(); String[] HASiteHostAndPort = HASite.Split(':'); String HASiteHost = HASiteHostAndPort[0]; int HASitePort = int.Parse(HASiteHostAndPort[1]); String HASiteAlias = HASiteHostAndPort[2]; sites[i] = new Site(HASiteHost, HASitePort); String HATopic = getTopic(HASiteHost, HASitePort, HASiteAlias, tableName, actionName); HATopicToTrueTopic_[HATopic] = topic; } } else { sites = new Site[] { new Site(host, port) }; lock (HATopicToTrueTopic_) { HATopicToTrueTopic_[topic] = topic; } } SubscribeInfo subscribeInfo = new SubscribeInfo(DateTime.Now, new BlockingCollection <List <IMessage> >(), sites, topic, offset, reconnect, filter, handler, tableName, actionName); subscribeInfo.setConnectState(ConnectState.REQUEST); queue = subscribeInfo.getQueue(); if (subscribeInfos_.ContainsKey(topic)) { throw new Exception("Subscription with topic " + topic + " exist. "); } else { subscribeInfos_.TryAdd(topic, subscribeInfo); } Console.WriteLine("Successfully subscribed table " + topic); } else { SubscribeInfo subscribeInfo = null; if (!subscribeInfos_.TryGetValue(topic, out subscribeInfo)) { throw new Exception("Subscription with topic " + topic + " doesn't exist. "); } lock (subscribeInfo) { if (subscribeInfo.getConnectState() == ConnectState.RECEIVED_SCHEMA) { throw new Exception("Subscription with topic " + topic + " the connection has been created. "); } subscribeInfo.setConnectState(ConnectState.REQUEST); } queue = subscribeInfo.getQueue(); } } } finally { dbConn.close(); } return(queue); }
public void run() { ConcurrentDictionary <string, SubscribeInfo> subscribeInfos = dispatcher_.getSubscribeInfos(); Socket socket = this.socket_; try { if (bis_ == null) { bis_ = new BufferedStream(new NetworkStream(socket)); } ExtendedDataInput @in = null; while (!dispatcher_.isClose()) { if (@in == null) { bool isLittle = bis_.ReadByte() != 0; if (isLittle) { @in = new LittleEndianDataInputStream(bis_); } else { @in = new BigEndianDataInputStream(bis_); } } else { @in.readBoolean(); } @in.readLong(); long msgid = @in.readLong(); topics = @in.readString(); short flag = @in.readShort(); IEntityFactory factory = new BasicEntityFactory(); int form = flag >> 8; int type = flag & 0xff; bool extended = type >= 128; if (type >= 128) { type -= 128; } if (form < 0 || form > MAX_FORM_VALUE) { throw new IOException("Invalid form value: " + form); } if (type < 0 || type > MAX_TYPE_VALUE) { throw new IOException("Invalid type value: " + type); } DATA_FORM df = (DATA_FORM)form; DATA_TYPE dt = (DATA_TYPE)type; IEntity body; try { body = factory.createEntity(df, dt, @in, extended); } catch { throw; } if (body.isTable()) { foreach (string HATopic in topics.Split(',')) { string topic = dispatcher_.getTopicForHATopic(HATopic); if (topic == null) { throw new Exception("Subscription with topic " + HATopic + " does not exist. "); } if (!successTopics.Contains(topic)) { SubscribeInfo subscribeInfo = null; //Prevents a situation where streaming data arrives earlier than the subscription succeeds. lock (subscribeInfos) { if (!subscribeInfos.TryGetValue(topic, out subscribeInfo)) { throw new Exception("Subscription with topic " + topic + " does not exist. "); } } lock (subscribeInfo) { if (subscribeInfo.getConnectState() != ConnectState.RECEIVED_SCHEMA) { subscribeInfo.setConnectState(ConnectState.RECEIVED_SCHEMA); } else { throw new Exception("Subscription with topic " + topic + " already has a thread parsing the stream data. "); } } successTopics.Add(topic); } } } else if (body.isVector()) { foreach (string HATopic in topics.Split(',')) { string topic = dispatcher_.getTopicForHATopic(HATopic); if (topic == null) { throw new Exception("Subscription with topic " + HATopic + " does not exist. "); } SubscribeInfo subscribeInfo = null; if (!subscribeInfos.TryGetValue(topic, out subscribeInfo)) { throw new Exception("Subscription with topic " + topic + " does not exist. "); } BasicAnyVector dTable = (BasicAnyVector)body; int colSize = dTable.rows(); int rowSize = dTable.getEntity(0).rows(); if (rowSize == 1) { BasicMessage rec = new BasicMessage(msgid, topic, dTable); dispatcher_.dispatch(rec); } else if (rowSize > 1) { List <IMessage> messages = new List <IMessage>(rowSize); for (int i = 0; i < rowSize; i++) { BasicAnyVector row = new BasicAnyVector(colSize); for (int j = 0; j < colSize; j++) { AbstractVector vector = (AbstractVector)dTable.getEntity(j); IEntity entity = vector.get(i); row.setEntity(j, entity); } BasicMessage rec = new BasicMessage(msgid, topic, row); messages.Add(rec); } dispatcher_.batchDispatch(messages); } lock (subscribeInfo) { subscribeInfo.setMsgId(msgid); } } } else { throw new Exception("message body has an invalid format. Vector or table is expected"); } } } catch (Exception e) { System.Console.Out.WriteLine(e.StackTrace); foreach (string topic in successTopics) { SubscribeInfo subscribeInfo = null; if (!subscribeInfos.TryGetValue(topic, out subscribeInfo)) { System.Console.Out.WriteLine("Subscription with topic " + topic + " doesn't exist. "); } else { lock (subscribeInfo) { subscribeInfo.setConnectState(ConnectState.NO_CONNECT); } } } } finally { try { socket.Close(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.Write(ex.StackTrace); } } Console.WriteLine("MessageParser thread stopped."); }