Example #1
0
/**
* process subscriber commands
* when feed command is received, data must be received within 30 seconds or subscriber will unsubscribe
 */
func (s *Subscriber) subscriberCommandProcess(h *Hub) {
	l.If("subscriber process - %s - start", s.id)
	defer l.If("subscriber process - %s - end", s.id)

	for {
		select {
		case subscriberCommand := <-s.commandListener:
			switch subscriberCommand.command {
			case SubscriberStop:
				l.If("subscriber process - %s - stop", s.id)
				return
			case SubscriberFeed:
				l.If("subscriber process - %s - feed", s.id)
				select {
				case s.feedListener <- subscriberCommand.SubscriberFeedCommand:
				case <-time.After(30 * time.Second):
					l.Wf("subscriber process - %s - feed timedout", s.id)
					h.subscriberCommandListener <- HubSubscriberRequest{Unsubscribe, s.id, nil, nil}
					return
				}
			}
		case <-time.After(30 * time.Second):
			l.If("subscriber process - %s - alive", s.id)
		}
	}

}
Example #2
0
/**
* handles adding, removing, cleaning and feeding subscribers
 */
func (h *Hub) subscribersProcess() {
	l.I("subscribers process - starting")
	for {
		select {
		case newData := <-h.subscriberFeedListener:
			l.If("subscribers process - newData", newData)
			for _, subscriber := range h.subscribers {
				if subscriber.channels[newData.channelData.ChannelName] != nil {
					select {
					case subscriber.commandListener <- SubscriberControlCommand{SubscriberFeed, CreateSingleFeedCommad(string(newData.operation), newData.channelData.ChannelName, newData.channelData.Data, newData.channelData.DataVersion)}:
					default:
						l.Wf("subscribers process - did not deliver new data to %s - queue full", subscriber.id)
					}
				}
			}
		case subscriberCommand := <-h.subscriberCommandListener:
			switch subscriberCommand.command {
			case Subscribe:
				l.I("subscribers process - subscribe")
				newSubscriber := h.createSubscriber(subscriberCommand.channels)
				subscriberCommand.responseListener <- newSubscriber
			case Unsubscribe:
				l.If("subscribers process - %s - unsubscribe", subscriberCommand.subscriberId)
				h.deleteSubscriber(subscriberCommand.subscriberId)
				subscriberCommand.responseListener <- Subscriber{}
			case SubscribeToChannels:
				l.If("subscribers process - %s - subscribe to channels", subscriberCommand.subscriberId, subscriberCommand.channels)
				if subscriber, found := h.subscribers[subscriberCommand.subscriberId]; found == true {
					h.addChannelsToSubscriber(subscriberCommand.channels, subscriber)
					subscriberCommand.responseListener <- *subscriber
				} else {
					subscriberCommand.responseListener <- Subscriber{}
				}
			case UnsubscribeFromChannels:
				l.If("subscribers process - %s - unsubscribe from channels", subscriberCommand.subscriberId, subscriberCommand.channels)
				if subscriber, found := h.subscribers[subscriberCommand.subscriberId]; found == true {
					h.removeChannelsFromSubscriber(subscriberCommand.channels, subscriber)
					subscriberCommand.responseListener <- *subscriber
				} else {
					subscriberCommand.responseListener <- Subscriber{}
				}
			case CleanupSubscribers:
				var cleanupStartTime = time.Now().Unix()
				for id, subscriber := range h.subscribers {
					if cleanupStartTime-subscriber.lastRequest > secondsToKeepSubscriberAlive {
						l.If("subscribers process - found dead subscriber %s", id)
						h.deleteSubscriber(id)
					}
				}
			}
		case <-time.After(30 * time.Second):
			l.If("subscribers process - alive")
		}
	}
	l.I("subscribers process - stopped")
}
Example #3
0
func (h *Hub) onServeFileRequest(m DataMediator, file string) {
	b, err := ioutil.ReadFile("web/" + file)
	if err != nil {
		l.Wf("file not found %s", "web/"+file)
	}
	if err == nil {
		l.Df("found file %s", file)
		m.WriteResponse(string(b), "plain")
	}
}
Example #4
0
func (m *WebSocketHandler) reader() {
	l.I("wsreader process - starting")
	var subscriberId string = "anonymous"
	for {
		var message string
		err := websocket.Message.Receive(m.ws, &message)
		if err != nil {
			l.If("wsreader process - %s - error reading from socket: %s", subscriberId, err.Error())
			break
		}
		l.If("wsreader process - read from socket %s", string(message))
		var command = new(WebSocketCommand)
		err = json.Unmarshal([]byte(message), command)
		if err != nil {
			l.Ef("wsreader process - %s - error unmarshal commad %s", subscriberId, err.Error())
			break
		}
		var mediator = WebSocketDataMediator{send: m.send, command: *command, RequestId: command.RequestId}
		// special commands - keep alive and subscribe
		if command.Command == "keepAlive" {
			var subscriber = m.hub.subscribers[m.subscriber.id]
			// subscriber not found
			if subscriber == nil {
				l.Wf("wsreader process - %s - timed out!", subscriberId)
				break
			} else {
				subscriber.lastRequest = time.Now().Unix()
			}
		} else if command.Command == "subscribe" {
			var channels = strings.Split(mediator.ReadParameter("channels"), ",")
			var responseListener = make(chan Subscriber)
			m.hub.subscriberCommandListener <- HubSubscriberRequest{command: Subscribe, channels: channels, responseListener: responseListener}
			m.subscriber = <-responseListener
			subscriberId = m.subscriber.id
			go m.writer()
			mediator.WriteResponse(map[string]interface{}{"command": "subscribe", "subscriberId": m.subscriber.id}, "json")
			close(responseListener)
		} else {
			m.hub.route(command.Command, &mediator)
		}
	}
	m.closeListener <- true
	l.If("wsreader process - %s - stopped", subscriberId)
	m.ws.Close()
}
Example #5
0
func main() {
	path, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	l.If("current app path: %s", path)
	var processes = runtime.NumCPU()
	runtime.GOMAXPROCS(processes)
	l.If("using processes %d", processes)
	l.I("server started.")
	restartLisnener := make(chan string)
	hub := comet.NewHub()
	for {
		go httpServerProcess(hub, restartLisnener)
		reason := <-restartLisnener
		l.Wf("web server restarted: %s", reason)
	}

}