func DataPull(txn *cheshire.Txn) { part, ok := txn.Params().GetInt("partition") if !ok { cheshire.SendError(txn, 406, fmt.Sprintf("partition param is manditory")) return } dataChan := make(chan *dynmap.DynMap, 10) finishedChan := make(chan int) errorChan := make(chan error) go func() { for { select { case data := <-dataChan: //send a data packet res := cheshire.NewResponse(txn) res.SetTxnStatus("continue") res.Put("data", data) txn.Write(res) case <-finishedChan: res := cheshire.NewResponse(txn) res.SetTxnStatus("complete") txn.Write(res) return case err := <-errorChan: cheshire.SendError(txn, 406, fmt.Sprintf("Unable to unlock (%s)", err)) return } } }() manager.partitioner.Data(part, dataChan, finishedChan, errorChan) }
func ServiceGet(txn *cheshire.Txn) { routerTable, ok := Servs.RouterTable(txn.Params().MustString("service", "")) if !ok { cheshire.SendError(txn, 406, "Service param missing or service not found") return } res := cheshire.NewResponse(txn) res.Put("router_table", routerTable.ToDynMap()) txn.Write(res) }
// a demo Firehose controller func Firehose(txn *cheshire.Txn) { for i := 0; true; i++ { response := cheshire.NewResponse(txn) response.Put("iteration", i) response.Put("data", "This is a firehose, I never stop") response.SetTxnStatus("continue") //set the status to continue so clients know to expect more responses txn.Write(response) time.Sleep(200 * time.Millisecond) } }
func Checkin(txn *cheshire.Txn) { table, err := manager.RouterTable() revision := int64(0) if err == nil { revision = table.Revision } response := cheshire.NewResponse(txn) response.Put("rt_revision", revision) response.Put("ts", time.Now()) txn.Write(response) }
func GetRouterTable(txn *cheshire.Txn) { log.Println("GetRouterTable") tble, err := manager.RouterTable() if err != nil { cheshire.SendError(txn, 506, fmt.Sprintf("Error: %s", err)) return } response := cheshire.NewResponse(txn) response.Put("router_table", tble.ToDynMap()) txn.Write(response) }
func Unlock(txn *cheshire.Txn) { partition, ok := txn.Params().GetInt("partition") if !ok { cheshire.SendError(txn, 406, fmt.Sprintf("partition param missing")) return } err := manager.UnlockPartition(partition) if err != nil { //now send back an error cheshire.SendError(txn, 406, fmt.Sprintf("Unable to lock partitions (%s)", err)) return } response := cheshire.NewResponse(txn) txn.Write(response) }
// Gets any logging messages from the Servs.Events // sends to client func ConsoleLog(txn *cheshire.Txn) { msgChan := make(chan clog.LoggerEvent, 10) Servs.Logger.Listen(msgChan) defer Servs.Logger.Unlisten(msgChan) log.Println("Log Listener Registered") for { msg := <-msgChan res := cheshire.NewResponse(txn) res.SetTxnStatus("continue") res.PutWithDot("event.type", msg.Type) res.PutWithDot("event.message", msg.Message) _, err := txn.Write(res) if err != nil { //try and write an error response cheshire.SendError(txn, 510, fmt.Sprintf("%s", err)) break } } log.Println("Log Listener unregistered") }
func SetRouterTable(txn *cheshire.Txn) { rtmap, ok := txn.Params().GetDynMap("router_table") if !ok { cheshire.SendError(txn, 406, "No router_table") return } rt, err := ToRouterTable(rtmap) if err != nil { cheshire.SendError(txn, 406, fmt.Sprintf("Unparsable router table (%s)", err)) return } _, err = manager.SetRouterTable(rt) if err != nil { cheshire.SendError(txn, 406, fmt.Sprintf("Unable to set router table (%s)", err)) return } response := cheshire.NewResponse(txn) txn.Write(response) }
// Do the request func (this *Router) doReq(txn *cheshire.Txn) { keyParams := this.connections.RouterTable().PartitionKeys partitionFound := false vals := make([]string, len(keyParams)) for i, k := range keyParams { v, ok := txn.Request.Params().GetString(k) if ok { partitionFound = true } vals[i] = v } if !partitionFound { //uhh, return error, or broadcast? } partitionKey := strings.Join(vals, "|") log.Printf("partition key %s", partitionKey) //Now partition //TODO partition := 0 //P.Partition(partitionKey) //Add the required params txn.Request.Params().Put(shards.P_PARTITION, partition) txn.Request.Params().Put(shards.P_ROUTER_TABLE_V, this.connections.RouterTable().Revision) queryType := txn.Request.Params().MustString(shards.P_QUERY_TYPE, "all") //Do the damn api call! max := 5 if queryType == "all_q" { max = 100 } a := &apiRR{ partition: partition, queryType: queryType, responses: make(map[string]*cheshire.Response), txn: txn, response: cheshire.NewResponse(txn), count: 0, max: max, } //send response. if len(a.responses) == 0 { // set the error response a.response.SetStatus(501, "Unable to get a single response.") } for k, r := range a.responses { r.Put("server_id", k) a.response.AddToSlice("responses", r) } //send the response. txn.Write(a.response) }
// a demo Ping controller function func Ping(txn *cheshire.Txn) { response := cheshire.NewResponse(txn) response.Put("data", "PONG") txn.Write(response) }
// Creates a new shard. Does not register any partitions to it, unless the router table has no entries. in which case this // gets all the partitions func ShardNew(txn *cheshire.Txn) { routerTable, ok := Servs.RouterTable(txn.Params().MustString("service", "")) if !ok { cheshire.SendError(txn, 406, "Service param missing or service not found") return } Servs.Logger.Printf("Creating new shard for service: %s", routerTable.Service) address, ok := txn.Params().GetString("address") if !ok { cheshire.SendError(txn, 406, "address param missing") return } jsonPort, ok := txn.Params().GetInt("json_port") if !ok { cheshire.SendError(txn, 406, "json_port param missing") return } httpPort, ok := txn.Params().GetInt("http_port") if !ok { cheshire.SendError(txn, 406, "http_port param missing") return } entry := &shards.RouterEntry{ Address: address, JsonPort: jsonPort, HttpPort: httpPort, Partitions: make([]int, 0), } //check if we can connect! Servs.Logger.Printf("Attempting to connect to new entry...") // _, _, err := EntryCheckin(routerTable, entry) // if err != nil { // cheshire.SendError(txn, 406, fmt.Sprintf("Unable to contact %s:%d Error(%s)", entry.Address, entry.HttpPort, err)) // return // } Servs.Logger.Printf("Success!") if len(routerTable.Entries) == 0 { totalPartitions, ok := txn.Params().GetInt("total_partitions") if !ok { cheshire.SendError(txn, 406, "total_partitions param is manditory for the first entry") return } //first entry, giving it all the partitions Servs.Logger.Printf("First Entry! giving it all %d partitions", totalPartitions) partitions := make([]int, 0) for p := 0; p < totalPartitions; p++ { partitions = append(partitions, p) } entry.Partitions = partitions } else { // not the first entry, } routerTable, err := routerTable.AddEntries(entry) if err != nil { cheshire.SendError(txn, 501, fmt.Sprintf("Error on add entry %s", err)) return } Servs.Logger.Printf("Successfully created new entry: %s", entry.Id()) Servs.SetRouterTable(routerTable) res := cheshire.NewResponse(txn) res.Put("router_table", routerTable.ToDynMap()) txn.Write(res) }