Esempio n. 1
0
func NewHubRepository() *HubRepository {
	var repository = new(HubRepository)
	repository.channels = make(map[string]*Channel)
	repository.getChannelListener = make(chan HubRepositoryChannelGetCommand, expectedMaxSubscribers)
	repository.newDataListener = make(map[string]chan ChannelDataInputCommand, expectedMaxSubscribers)
	repository.getDataListener = make(map[string]chan ChannelDataRequestCommand, expectedMaxSubscribers)
	if restoreData {
		l.I("restoring channels")
		// read previous data
		var files, err = ioutil.ReadDir("data")
		if err == nil {
			for i := 0; i < len(files); i++ {
				var file = files[i]
				if !strings.HasSuffix(file.Name(), ".json") {
					continue
				}
				var data, err = ioutil.ReadFile("data/" + file.Name())
				if err == nil {
					l.If("restoring channel %s", file.Name())
					var channel = new(Channel)
					var err = json.Unmarshal(data, channel)
					if err == nil && strings.Trim(channel.ChannelName, "") != "" {
						repository.addCreatedChannel(channel)
					}
				}
			}
		}
		l.I("restoring channels completed.")
	}
	// start channel process
	go repository.channelProcess()

	return repository
}
Esempio n. 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")
}
Esempio n. 3
0
func (h *Hub) refreshStatusProcess() {
	l.I("status process - start")
	defer l.I("status process - end")
	for {
		var data, _ = json.Marshal(createHubStatus(h))
		h.subscriberCommandListener <- HubSubscriberRequest{CleanupSubscribers, "", nil, nil}
		h.AddNewDataToChannel("create", "system", string(data))
		l.I("status process - checked system")
		time.Sleep(refreshStatusPeriod)
	}
}
Esempio n. 4
0
func (r *HubRepository) channelProcess() {
	l.I("channels process - start")
	for {
		var channelRequest = <-r.getChannelListener
		var channel = r.channels[channelRequest.channelName]
		if channel == nil {
			l.If("channels process - add channel %s", channelRequest.channelName)
			channel = new(Channel)
			channel.ChannelName = channelRequest.channelName
			channel.DataVersion = 0
			channel.Data = ""
			r.addCreatedChannel(channel)
		}
		l.If("channels process - served channel %s", channelRequest.channelName)
		channelRequest.resultListener <- HubRepositoryChannelFeeds{newDataListener: r.newDataListener[channel.ChannelName], getDataListener: r.getDataListener[channel.ChannelName]}
	}

	l.I("channels process - end")
}
Esempio n. 5
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()
}
Esempio n. 6
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)
	}

}