Пример #1
0
// Process another node's response to a find_node query.
func (d *DHT) processFindNodeResults(node *remoteNode, resp responseType) {
	totalRecvFindNodeReply.Add(1)

	query, _ := node.pendingQueries[resp.T]

	if resp.R.Nodes != "" {
		for id, address := range parseNodesString(resp.R.Nodes) {
			_, addr, existed, err := d.routingTable.hostPortToNode(address)
			if err != nil {
				l4g.Trace("DHT error parsing node from find_find response: %v", err)
				continue
			}
			// SelfPromotions are more common for find_node. They are
			// happening even for router.bittorrent.com
			if existed {
				l4g.Trace(func() string {
					x := hashDistance(query.ih, InfoHash(node.id))
					return fmt.Sprintf("DHT: DUPE node reference, query %x: %x@%v from %x@%v. Distance: %x.", query.ih, id, address, node.id, addr, x)
				})
				totalDupes.Add(1)
			} else {
				l4g.Trace(func() string {
					x := hashDistance(query.ih, InfoHash(node.id))
					return fmt.Sprintf("DHT: Got new node reference, query %x: %x@%v from %x@%v. Distance: %x.", query.ih, id, address, node.id, addr, x)
				})
				if _, err := d.routingTable.getOrCreateNode(id, addr); err == nil {
					// Using d.findNode() instead of d.findNodeFrom() ensures
					// that only the closest neighbors are looked at.
					d.findNode(string(query.ih))
				}
			}
		}
	}
}
Пример #2
0
func (d *DHT) replyFindNode(addr *net.UDPAddr, r responseType) {
	totalRecvFindNode.Add(1)
	l4g.Trace(func() string {
		x := hashDistance(InfoHash(r.A.Target), InfoHash(d.nodeId))
		return fmt.Sprintf("DHT find_node. Host: %v , nodeId: %x , target ID: %x , distance to me: %x", addr, r.A.Id, r.A.Target, x)
	})

	node := InfoHash(r.A.Target)
	r0 := map[string]interface{}{"id": d.nodeId}
	reply := replyMessage{
		T: r.T,
		Y: "r",
		R: r0,
	}

	// XXX we currently can't give out the peer contact. Probably requires
	// processing announce_peer.  XXX If there was a total match, that guy
	// is the last.
	neighbors := d.routingTable.lookup(node)
	n := make([]string, 0, kNodes)
	for _, r := range neighbors {
		n = append(n, r.id+r.addressBinaryFormat)
	}
	l4g.Trace("replyFindNode: Nodes only. Giving %d", len(n))
	reply.R["nodes"] = strings.Join(n, "")
	sendMsg(d.conn, addr, reply)
}
Пример #3
0
func (es *ESocket) handleESRequest(request *ESRequest) (string, error) {

	if es.Running {

		buf := bytes.NewBufferString("sendmsg\n")
		buf.WriteString("call-command: " + request.Req_Com + "\n")
		buf.WriteString("execute-app-name: " + request.Req_App + "\n")
		if request.Req_Arg != "" && len(request.Req_Arg) > 0 {
			buf.WriteString("execute-app-arg: " + request.Req_Arg + "\n")
		}
		buf.WriteString("event-lock: true\n")
		l4g.Trace("SendRequest ---> : \n{%s}\n", buf.String())
		fmt.Fprintf(es.conn, "%s\n", buf.String())

		timeout := CheckTimeout(requestTimeout)
		select {
		case <-timeout:
			return "", errors.New("Timeout : " + request.Req_App)
		case res := <-es.cmd:
			l4g.Trace("Request res : %s", res.Header["Reply-Text"])
			return res.Header["Reply-Text"], nil
		case err := <-es.err:
			return "", err
		}

	} else {
		return "", errors.New("Conn already closed")
	}
}
Пример #4
0
Файл: krpc.go Проект: nhelke/dht
// newQuery creates a new transaction id and adds an entry to r.pendingQueries.
// It does not set any extra information to the transaction information, so the
// caller must take care of that.
func (r *remoteNode) newQuery(transType string) (transId string) {
	l4g.Trace("newQuery for %x, lastID %v", r.id, r.lastQueryID)
	r.lastQueryID = (r.lastQueryID + 1) % 256
	transId = strconv.Itoa(r.lastQueryID)
	l4g.Trace("... new id %v", r.lastQueryID)
	r.pendingQueries[transId] = &queryType{Type: transType}
	return
}
Пример #5
0
func (r *MongoPromiseTicketRepository) Add(promise *model.PromiseTicket) error {

	err := r.collection.Insert(&promise)

	if err != nil {
		log.Trace("error while inserting document in Mongo: %v", err)
	} else {
		log.Trace("new document inserted into mongo with id: %v", promise)
	}

	return err
}
func (r *MongoCallbackAttemptRepository) Add(promise *model.CallbackAttempt) error {
	promise.Id = bson.NewObjectId()

	err := r.collection.Insert(&promise)

	if err != nil {
		log.Trace("error while inserting document in Mongo: %v", err)
	} else {
		log.Trace("new document inserted into mongo with id: %v", promise.Id)
	}

	return err
}
Пример #7
0
Файл: dht.go Проект: rakoo/dht
// Process another node's response to a find_node query.
func (d *DHT) processFindNodeResults(node *remoteNode, resp responseType) {
	totalRecvFindNodeReply.Add(1)

	query, _ := node.pendingQueries[resp.T]

	if resp.R.Nodes != "" {
		for id, address := range parseNodesString(resp.R.Nodes) {
			_, addr, existed, err := d.routingTable.hostPortToNode(address)
			if err != nil {
				l4g.Trace("DHT error parsing node from find_find response: %v", err)
				continue
			}
			if addr == node.address.String() {
				// SelfPromotions are more common for find_node. They are
				// happening even for router.bittorrent.com
				totalSelfPromotions.Add(1)
				continue
			}
			if existed {
				l4g.Trace(func() string {
					x := hashDistance(query.ih, InfoHash(node.id))
					return fmt.Sprintf("DHT: processFindNodeResults DUPE node reference, query %x: %x@%v from %x@%v. Distance: %x.",
						query.ih, id, address, node.id, node.address, x)
				})
				totalFindNodeDupes.Add(1)
			} else {
				l4g.Trace(func() string {
					x := hashDistance(query.ih, InfoHash(node.id))
					return fmt.Sprintf("DHT: Got new node reference, query %x: %x@%v from %x@%v. Distance: %x.",
						query.ih, id, address, node.id, node.address, x)
				})
				// Includes the node in the routing table and ignores errors.
				//
				// Only continue the search if we really have to.
				_, err := d.routingTable.getOrCreateNode(id, addr)

				if err == nil && d.needMoreNodes() {
					select {
					case d.nodesRequest <- ihReq{query.ih, false}:
					default:
						// Too many find_node commands queued up. Dropping
						// this. The node has already been added to the
						// routing table so we're not losing any
						// information.
					}
				}
			}
		}
	}
}
Пример #8
0
func (r *routingTable) cleanup() (needPing []*remoteNode) {
	needPing = make([]*remoteNode, 0, 10)
	t0 := time.Now()
	// Needs some serious optimization.
	for addr, n := range r.addresses {
		if addr != n.address.String() {
			l4g.Warn("cleanup: node address mismatches: %v != %v. Deleting node", addr, n.address.String())
			r.kill(n)
			continue
		}
		if addr == "" {
			l4g.Warn("cleanup: found empty address for node %x. Deleting node", n.id)
			r.kill(n)
			continue
		}
		if n.reachable {
			if len(n.pendingQueries) == 0 {
				goto PING
			}
			// Tolerate 2 cleanup cycles.
			if time.Since(n.lastResponseTime) > cleanupPeriod*2+(time.Minute) {
				l4g.Trace("DHT: Old node seen %v ago. Deleting", time.Since(n.lastResponseTime))
				r.kill(n)
				continue
			}
			if time.Since(n.lastResponseTime).Nanoseconds() < cleanupPeriod.Nanoseconds()/2 {
				// Seen recently. Don't need to ping.
				continue
			}

		} else {
			// Not reachable.
			if len(n.pendingQueries) > 2 {
				// Didn't reply to 2 consecutive queries.
				l4g.Trace("DHT: Node never replied to ping. Deleting. %v", n.address)
				r.kill(n)
				continue
			}
		}
	PING:
		needPing = append(needPing, n)
	}
	duration := time.Since(t0)
	// If this pauses the server for too long I may have to segment the cleanup.
	// 2000 nodes: it takes ~12ms
	// 4000 nodes: ~24ms.
	l4g.Info("DHT: Routing table cleanup took %v", duration)
	return needPing
}
Пример #9
0
func (d *DHT) peersForInfoHash(ih InfoHash) []string {
	peerContacts := d.peerStore.peerContacts(ih)
	if len(peerContacts) > 0 {
		l4g.Trace("replyGetPeers: Giving peers! %x was requested, and we knew %d peers!", ih, len(peerContacts))
	}
	return peerContacts
}
Пример #10
0
func (es *ESocket) SendCmd(cmd string) (string, error) {

	if es.Running {
		l4g.Debug("Send cmd --> %s", cmd)
		fmt.Fprintf(es.conn, "%s\n\n", cmd)

		timeout := CheckTimeout(requestTimeout)
		select {
		case <-timeout:
			return "", errors.New("Timeout : " + cmd)
		case res := <-es.cmd:
			l4g.Trace("Request res : %s--%s", res.Header["Reply-Text"], res.Header["Channel-Unique-Id"])
			if strings.Contains(res.Header["Reply-Text"], "OK") {
				if len(res.Header["Channel-Unique-Id"]) > 0 {
					return res.Header["Channel-Unique-Id"], nil
				}
				return res.Header["Reply-Text"], nil
			} else {
				return "", errors.New(res.Header["Reply-Text"])
			}
		case err := <-es.err:
			return "", err
		}
	} else {
		return "", errors.New("Conn already closed")
	}

}
Пример #11
0
// Apply executes a set of sqlite statements, within a transaction. All statements
// will take effect, or none.
func (c *TransactionExecuteCommandSet) Apply(server raft.Server) (interface{}, error) {
	log.Trace("Applying TransactionExecuteCommandSet of size %d", len(c.Stmts))

	commitSuccess := false
	db := server.Context().(*db.DB)
	defer func() {
		if !commitSuccess {
			err := db.RollbackTransaction()
			if err != nil {
				log.Error("Failed to rollback transaction: %s", err.Error)
			}
		}
	}()

	err := db.StartTransaction()
	if err != nil {
		log.Error("Failed to start transaction:", err.Error())
		return nil, err
	}
	for i := range c.Stmts {
		err = db.Execute(c.Stmts[i])
		if err != nil {
			log.Error("Failed to execute statement within transaction", err.Error())
			return nil, err
		}
	}
	err = db.CommitTransaction()
	if err != nil {
		log.Error("Failed to commit transaction:", err.Error())
		return nil, err
	} else {
		commitSuccess = true
	}
	return nil, nil
}
Пример #12
0
func main() {

	runtime.GOMAXPROCS(runtime.NumCPU())
	//l4g.AddFilter("file", l4g.FINE, l4g.NewFileLogWriter("server.log", false))
	// creates a tcp listener
	l4g.LoadConfiguration("./conf/log4go.xml")
	tcpAddr, err := net.ResolveTCPAddr("tcp4", ":8989")
	checkError(err)
	listener, err := net.ListenTCP("tcp", tcpAddr)
	checkError(err)
	defer l4g.Close()
	// creates a server
	config := &gotcp.Config{
		PacketSendChanLimit:    20,
		PacketReceiveChanLimit: 20,
	}
	srv := gotcp.NewServer(config, &Callback{}, &echo.EchoProtocol{})

	// starts service
	go srv.Start(listener, time.Second)
	l4g.Debug("listening: %s", listener.Addr())
	//log.Println("listening:", listener.Addr())

	// catchs system signal
	chSig := make(chan os.Signal)
	signal.Notify(chSig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR2) //, syscall.SIGINT, syscall.SIGTERM
	l4g.Trace("Signal: %s", <-chSig)
	//log.Println("Signal: ", <-chSig)

	// stops service
	srv.Stop()
}
Пример #13
0
func main() {
	logger.LoadConfiguration("logging.xml")
	logger.Trace("main start")

	logger.Trace("CPU NUM: %d", runtime.NumCPU())
	runtime.GOMAXPROCS(runtime.NumCPU())

	//static directories
	http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("./css/"))))
	http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("./js/"))))
	http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./img/"))))

	handler.InitRoutes()

	http.HandleFunc("/", handler.RouteHandler)
	http.ListenAndServe(":8080", nil)
}
Пример #14
0
Файл: dht.go Проект: rakoo/dht
func (d *DHT) nodesForInfoHash(ih InfoHash) string {
	n := make([]string, 0, kNodes)
	for _, r := range d.routingTable.lookup(ih) {
		// r is nil when the node was filtered.
		if r != nil {
			binaryHost := r.id + nettools.DottedPortToBinary(r.address.String())
			if binaryHost == "" {
				l4g.Trace("killing node with bogus address %v", r.address.String())
				d.routingTable.kill(r)
			} else {
				n = append(n, binaryHost)
			}
		}
	}
	l4g.Trace("replyGetPeers: Nodes only. Giving %d", len(n))
	return strings.Join(n, "")
}
Пример #15
0
Файл: dht.go Проект: rakoo/dht
func (d *DHT) findNodeFrom(r *remoteNode, id string) {
	totalSentFindNode.Add(1)
	ty := "find_node"
	transId := r.newQuery(ty)
	ih := InfoHash(id)
	l4g.Trace("findNodeFrom adding pendingQueries transId=%v ih=%x", transId, ih)
	r.pendingQueries[transId].ih = ih
	queryArguments := map[string]interface{}{
		"id":     d.nodeId,
		"target": id,
	}
	query := queryMessage{transId, "q", ty, queryArguments}
	l4g.Trace(func() string {
		x := hashDistance(InfoHash(r.id), ih)
		return fmt.Sprintf("DHT sending find_node. nodeID: %x@%v, target ID: %x , distance: %x", r.id, r.address, id, x)
	})
	sendMsg(d.conn, r.address, query)
}
Пример #16
0
// announcePeer sends a message to the destination address to advertise that
// our node is a peer for this infohash, using the provided token to
// 'authenticate'.
func (d *DHT) announcePeer(address *net.UDPAddr, ih InfoHash, token string) {
	r, err := d.routingTable.getOrCreateNode("", address.String())
	if err != nil {
		l4g.Trace("announcePeer:", err)
		return
	}
	ty := "announce_peer"
	l4g.Trace("DHT: announce_peer => %v %x %x\n", address, ih, token)
	transId := r.newQuery(ty)
	queryArguments := map[string]interface{}{
		"id":        d.nodeId,
		"info_hash": ih,
		"port":      d.port,
		"token":     token,
	}
	query := queryMessage{transId, "q", ty, queryArguments}
	sendMsg(d.conn, address, query)
}
Пример #17
0
func (d *DHT) replyPing(addr *net.UDPAddr, response responseType) {
	l4g.Trace("DHT: reply ping => %v\n", addr)
	reply := replyMessage{
		T: response.T,
		Y: "r",
		R: map[string]interface{}{"id": d.nodeId},
	}
	sendMsg(d.conn, addr, reply)
}
Пример #18
0
func (es *ESocket) AnswerCall() (string, error) {
	req := newESRequest("execute", "answer")
	res, err := es.handleESRequest(req)
	if err != nil {
		l4g.Warn("AnswerCall failure for : %s", err.Error())
		return "", err
	}
	l4g.Trace("AnswerCall ok.")
	return res, nil
}
Пример #19
0
func (node MenuNode) Execute(ivrChannel *IVRChannel) (string, error) {

	if ivrChannel.ChannelState == IVRChannel_State_Hangup {
		return "", errors.New("channel state is invalid : hangup")
	}

	ivrChannel.ActiveNode = node.NodeName
	// Clear dtmf channel value.
	for len(ivrChannel.Dtmf) > 0 {
		<-ivrChannel.Dtmf
	}

	executePrompt(node.Prompts.Prompt, ivrChannel)

	/*
		if len(node.Prompts.Prompt) > 0 {
			for _, promptName := range node.Prompts.Prompt {
				// Find prompt from ivrPromptMap by promptName
				if prompt, ok := ivrPromptMap[promptName]; ok {
					executePrompt(prompt, ivrChannel)
					<-ivrChannel.PlaybackDone
				} else {
					l4g.Warn("Prompt not find for promptName=%s", promptName)
				}
			}
		}
	*/

	ivrChannel.Esocket.StartDTMF()
	defer ivrChannel.Esocket.StopDTMF()

	// Wait dtmf input.
	timeout := eventsocket.CheckTimeout(node.Timeout)
	select {
	case <-timeout:
		l4g.Warn("Timeout,no dtmf.")
		ivrChannel.NoInputTimes = ivrChannel.NoInputTimes + 1
		return node.NoInput, nil
	case dtmf := <-ivrChannel.Dtmf:

		for _, choice := range node.Choices.Choice {
			if dtmf == choice.DTMF {
				return choice.NextNode, nil
			}
		}

		l4g.Warn("No match for dtmf=%s", dtmf)
		ivrChannel.NoMatchTimes = ivrChannel.NoMatchTimes + 1
		return node.NoMatch, nil
	case <-ivrChannel.ChannelHangup:
		l4g.Trace("Channel hangup.")
		return "", errors.New("Channel hangup.")
	}

}
Пример #20
0
func (channel *IVRChannel) OnEvent(event *eventsocket.Event) {

	if event != nil {
		l4g.Debug("------------------------> New Event eventName=%s,callId=%s", event.Header["Event-Name"], event.Header["Channel-Call-UUID"])
		if event.Header["Channel-Call-UUID"] == channel.ChannelId {
			if eventName, ok := event.Header["Event-Name"]; ok {
				l4g.Trace("IVR onEvent ----->  %s", eventName)
				if "DTMF" == eventName {
					dtmf, _ := event.Header["DTMF-Digit"]
					l4g.Trace("Rec new dtmf value -> %s", dtmf)
					channel.Dtmf <- dtmf
				}
				if "PLAYBACK_STOP" == eventName {
					if playStatus := event.Header["Playback-Status"]; "break" == playStatus {
						channel.PlaybackDone <- true
					} else {
						channel.PlaybackDone <- false
					}
				}

				if "CHANNEL_ANSWER" == eventName {
					channel.ChannelState = IVRChannel_State_Service
					channel.CallParams["ANI"] = event.Header["Caller-Orig-Caller-ID-Number"]
					channel.CallParams["DNIS"] = event.Header["Caller-Destination-Number"]
					channel.CallParams["callId"] = event.Header["Channel-Call-UUID"]
					channel.CallParams["connId"] = event.Header["Unique-ID"]
					channel.ChannelId = event.Header["Channel-Call-UUID"]
					l4g.Trace("Show CallInfo ani=%s,dnis=%s,callId=%s,connId=%s", channel.CallParams["ANI"], channel.CallParams["DNIS"], channel.CallParams["callId"], channel.CallParams["connId"])
				}

			}
		}

		if "HANGUP" == event.Header["Event-Name"] {
			channel.Esocket.Running = false
			channel.Esocket.Close()
			channel.ChannelState = IVRChannel_State_Hangup
			channel.ChannelHangup <- true // Channel hangup.
			l4g.Info("Rec client disconnected event and close channel.")
		}
	}
}
Пример #21
0
func (source EventSource) getHandler(key string) EventHandler {
	log.Trace("Getting handler for key %v.", key)

	handler := source.handlers[key]

	if handler == nil {
		log.Warn("No handler found.")
	}

	return handler
}
Пример #22
0
func (d *DHT) nodesForInfoHash(ih InfoHash) string {
	n := make([]string, 0, kNodes)
	for _, r := range d.routingTable.lookup(ih) {
		// r is nil when the node was filtered.
		if r != nil {
			n = append(n, r.id+nettools.DottedPortToBinary(r.address.String()))
		}
	}
	l4g.Trace("replyGetPeers: Nodes only. Giving %d", len(n))
	return strings.Join(n, "")
}
Пример #23
0
func (r *routingTable) addNewNeighbor(n *remoteNode, displaceBoundary bool) {
	if err := r.insert(n); err != nil {
		l4g.Warn("addNewNeighbor: %v", err)
		return
	}
	if displaceBoundary && r.boundaryNode != nil {
		// This will also take care of setting a new boundary.
		r.kill(r.boundaryNode)
	} else {
		r.resetNeighborhoodBoundary()
	}
	l4g.Trace("New neighbor added to neighborhood with proximity %d", r.proximity)
}
Пример #24
0
func Connect(server, database_name, login, password string) (DataBase, error) {
	l4g.Trace("Inside Connect")
	var db DataBase

	// Create client
	client, err := rest.New(HTTP_PREFIX + server)

	if err == nil {
		l4g.Trace("Getting token...")
		client.SetBasicAuth(login, password)
		err = client.GetHeaders(CONNECT_URL + database_name)

		if err == nil {
			l4g.Trace("Creating database structure...")
			db = DataBase{name: database_name,
				server: server,
				client: client}
		}
	}

	return db, err
}
Пример #25
0
func (source EventSource) Apply(e interface{}) {
	key := getEventKey(e)

	log.Trace("Invoking handler now.")
	handler := source.getHandler(key)
	err := handler(e)

	if err != nil {
		log.Warn("Handler returned error: %v", err.Error())
	} else {
		log.Trace("Handler executed successfully")
	}

	// refl := reflect.ValueOf(source)
	// methNum := refl.NumMethod()

	// log.Trace("found %v methods on %v", methNum, refl.Type())

	// for i := 0; i < methNum; i++ {
	// 	method := refl.Method(i)
	// 	methodInfo := method.Type()

	// 	log.Trace("[%v/%v] looking at method %v.", i+1, methNum, methodInfo.String())

	// 	if methodInfo.NumIn() != 1 {
	// 		log.Trace("skipping method because it has %v arguments", methodInfo.NumIn())
	// 		continue
	// 	}

	// 	if methodInfo.In(0).Kind() == reflect.TypeOf(e).Kind() {
	// 		args := make([]reflect.Value, 1)
	// 		args[0] = reflect.ValueOf(e)
	// 		///method.Call(args)

	// 		log.Trace("event has been applied")
	// 	}
	// }
}
Пример #26
0
func handleClient(clientConn net.Conn) {

	l4g.Trace("New client :%s", clientConn.RemoteAddr().String())

	ivrChannel := NewIVRChannel(clientConn)
	ivr.channelMap[ivrChannel.ChannelName] = *ivrChannel

	defer delete(ivr.channelMap, ivrChannel.ChannelName)
	defer clientConn.Close()

	LoadIVRConfig(Ivr_Config_File)

	ivr.ExecuteCallFlow("root", ivrChannel)

}
Пример #27
0
func (d *DHT) getPeersFrom(r *remoteNode, ih InfoHash) {
	totalSentGetPeers.Add(1)
	ty := "get_peers"
	transId := r.newQuery(ty)
	r.pendingQueries[transId].ih = ih
	queryArguments := map[string]interface{}{
		"id":        d.nodeId,
		"info_hash": ih,
	}
	query := queryMessage{transId, "q", ty, queryArguments}
	l4g.Trace(func() string {
		x := hashDistance(InfoHash(r.id), ih)
		return fmt.Sprintf("DHT sending get_peers. nodeID: %x , InfoHash: %x , distance: %x", r.id, ih, x)
	})
	sendMsg(d.conn, r.address, query)
}
Пример #28
0
func (d *DHT) replyAnnouncePeer(addr *net.UDPAddr, r responseType) {
	l4g.Trace(func() string {
		ih := InfoHash(r.A.InfoHash)
		return fmt.Sprintf("DHT: announce_peer. Host %v, nodeID: %x, infoHash: %x, peerPort %d, distance to me %x",
			addr, r.A.Id, ih, r.A.Port, hashDistance(ih, InfoHash(d.nodeId)),
		)
	})
	peerAddr := net.TCPAddr{IP: addr.IP, Port: r.A.Port}
	d.peerStore.addContact(InfoHash(r.A.InfoHash), nettools.DottedPortToBinary(peerAddr.String()))
	// Always reply positively. jech says this is to avoid "back-tracking", not sure what that means.
	reply := replyMessage{
		T: r.T,
		Y: "r",
		R: map[string]interface{}{"id": d.nodeId},
	}
	sendMsg(d.conn, addr, reply)
}
Пример #29
0
func (n *nTree) isOK(ih InfoHash) bool {
	if n.value == nil || n.value.id == "" {
		return false
	}
	r := n.value

	if len(r.pendingQueries) > maxNodePendingQueries {
		// debug.Println("DHT: Skipping because there are too many queries pending for this dude.")
		// debug.Println("DHT: This shouldn't happen because we should have stopped trying already. Might be a BUG.")
		return false
	}

	recent := r.wasContactedRecently(ih)
	l4g.Trace("wasContactedRecently for ih=%x in node %x@%v returned %v", ih, r.id, r.address, recent)
	if recent {
		return false
	}
	return true
}
Пример #30
0
func (this *Engine) RegisterHttpApi(path string,
	handlerFunc func(http.ResponseWriter,
		*http.Request, map[string]interface{}) (interface{}, error)) *mux.Route {
	wrappedFunc := func(w http.ResponseWriter, req *http.Request) {
		var (
			ret interface{}
			t1  = time.Now()
		)

		params, err := this.decodeHttpParams(w, req)
		if err == nil {
			ret, err = handlerFunc(w, req, params)
		}

		if err != nil {
			ret = map[string]interface{}{"error": err.Error()}
		}

		w.Header().Set("Content-Type", "application/json")
		var status int
		if err == nil {
			status = http.StatusOK
		} else {
			status = http.StatusInternalServerError
		}
		w.WriteHeader(status)

		// debug request body content
		log.Trace("req body: %+v", params)
		// access log
		log.Debug("%s \"%s %s %s\" %d %s",
			req.RemoteAddr,
			req.Method,
			req.RequestURI,
			req.Proto,
			status,
			time.Since(t1))
		if status != http.StatusOK {
			log.Error("ERROR %v", err)
		}

		if ret != nil {
			// pretty write json result
			pretty, _ := json.MarshalIndent(ret, "", "    ")
			w.Write(pretty)
			w.Write([]byte("\n"))
		}
	}

	// path can't be duplicated
	isDup := false
	for _, p := range this.httpPaths {
		if p == path {
			log.Error("REST[%s] already registered", path)
			isDup = true
			break
		}
	}

	if !isDup {
		this.httpPaths = append(this.httpPaths, path)
	}

	return this.httpRouter.HandleFunc(path, wrappedFunc)
}