func calculateRoomInstructionSets(r *Runner, hs b.Homeserver) [][]instruction {
	sets := make([][]instruction, r.roomConcurrency)

	// add instructions to create rooms and send events
	for roomIndex, room := range hs.Rooms {
		setIndex := indexFor(fmt.Sprintf("%d", roomIndex), r.roomConcurrency)
		instrs := sets[setIndex]
		var queryParams = make(map[string]string)
		if room.Creator != "" {
			storeRes := map[string]string{
				fmt.Sprintf("room_%d", roomIndex): ".room_id",
			}
			if room.Ref != "" {
				storeRes[fmt.Sprintf("room_ref_%s", room.Ref)] = ".room_id"

				// Store the homeserver's server_name, so that remote homeservers that attempt
				// to join this room know which server to contact
				r.lookup.Store(fmt.Sprintf("room_ref_%s_server_name", room.Ref), hs.Name)
			}
			instrs = append(instrs, instruction{
				method:        "POST",
				path:          "/_matrix/client/r0/createRoom",
				accessToken:   "user_" + room.Creator,
				body:          room.CreateRoom,
				storeResponse: storeRes,
			})
		} else if room.Ref == "" {
			log.Printf("HS %s room index %d must either have a Ref or a Creator\n", hs.Name, roomIndex)
			return nil
		}
		for eventIndex, event := range room.Events {
			method := "PUT"
			var path string
			subs := map[string]string{
				"$roomId":    fmt.Sprintf(".room_%d", roomIndex),
				"$eventType": event.Type,
			}
			if room.Ref != "" {
				subs["$roomId"] = fmt.Sprintf(".room_ref_%s", room.Ref)
			}
			if event.StateKey != nil {
				path = "/_matrix/client/r0/rooms/$roomId/state/$eventType/$stateKey"
				subs["$stateKey"] = *event.StateKey
			} else {
				path = "/_matrix/client/r0/rooms/$roomId/send/$eventType/$txnId"
				subs["$txnId"] = fmt.Sprintf("%d", eventIndex)
			}

			// special cases: room joining, leaving and inviting
			if event.Type == "m.room.member" && event.StateKey != nil &&
				event.Content != nil && event.Content["membership"] != nil {
				membership, ok := event.Content["membership"].(string)
				if ok {
					switch membership {
					case "join":
						path = "/_matrix/client/r0/join/$roomId"
						method = "POST"

						// Set server_name to the homeserver that created the room, as they're a pretty
						// good candidate to join the room through
						queryParams["server_name"] = fmt.Sprintf(".room_ref_%s_server_name", room.Ref)
					case "leave":
						path = "/_matrix/client/r0/rooms/$roomId/leave"
						method = "POST"
						if *event.StateKey != event.Sender {
							// it's a kick
							path = "/_matrix/client/r0/rooms/$roomId/kick"
							method = "POST"
							event.Content["user_id"] = *event.StateKey
						}
					case "invite":
						path = "/_matrix/client/r0/rooms/$roomId/invite"
						method = "POST"
						event.Content["user_id"] = *event.StateKey
					}
				}
			} else if event.Type == "m.room.canonical_alias" && event.StateKey != nil &&
				*event.StateKey == "" {
				// create the alias first then send the canonical alias
				// keep a ref to the current room index so it's correct when bodyFn is called
				alias, ok := event.Content["alias"].(string)
				if ok {
					ri := roomIndex
					instrs = append(instrs, instruction{
						method:        "PUT",
						path:          "/_matrix/client/r0/directory/room/" + url.PathEscape(alias),
						accessToken:   fmt.Sprintf("user_%s", event.Sender),
						substitutions: subs,
						queryParams:   queryParams,
						bodyFn: func(lk *sync.Map) interface{} {
							val, _ := lk.Load(fmt.Sprintf("room_%d", ri))
							return map[string]interface{}{
								"room_id": val,
							}
						},
					})
				}
			}
			instrs = append(instrs, instruction{
				method:        method,
				path:          path,
				body:          event.Content,
				accessToken:   fmt.Sprintf("user_%s", event.Sender),
				substitutions: subs,
				queryParams:   queryParams,
			})
		}
		sets[setIndex] = instrs
	}

	return sets
}
// calculateRoomInstructionSets returns sets of HTTP requests to be executed in order. Sets can be executed in any order. Various substitutions
// and placeholders are returned in these instructions as it's impossible to know at this time what room IDs etc
// will be allocated, so use an instruction loader to load the right requests.
calculateRoomInstructionSets returns sets of HTTP requests to be executed in order. Sets can be executed in any order. Various substitutions
and placeholders are returned in these instructions as it's impossible to know at this time what room IDs etc
will be allocated, so use an instruction loader to load the right requests.
// calculateRoomInstructionSets returns sets of HTTP requests to be executed in order . Sets can be executed in any order . Various substitutions // and placeholders are returned in these instructions as it ' s impossible to know at this time what room IDs etc // will be allocated so use an instruction loader to load the right requests .
func calculateRoomInstructionSets(r *Runner, hs b.Homeserver) [][]instruction {
	sets := make([][]instruction, r.roomConcurrency)
	for roomIndex, room := range hs.Rooms {
		setIndex := indexFor(fmt.Sprintf("%d", roomIndex), r.roomConcurrency)
		instrs := sets[setIndex]
		var queryParams = make(map[string]string)
		if room.Creator != "" {
			storeRes := map[string]string{
				fmt.Sprintf("room_%d", roomIndex): ".room_id",
			}
			if room.Ref != "" {
				storeRes[fmt.Sprintf("room_ref_%s", room.Ref)] = ".room_id"
				r.lookup.Store(fmt.Sprintf("room_ref_%s_server_name", room.Ref), hs.Name)
			}
			instrs = append(instrs, instruction{
				method:        "POST",
				path:          "/_matrix/client/r0/createRoom",
				accessToken:   "user_" + room.Creator,
				body:          room.CreateRoom,
				storeResponse: storeRes,
			})
		} else if room.Ref == "" {
			log.Printf("HS %s room index %d must either have a Ref or a Creator\n", hs.Name, roomIndex)
			return nil
		}
		for eventIndex, event := range room.Events {
			method := "PUT"
			var path string
			subs := map[string]string{
				"$roomId":    fmt.Sprintf(".room_%d", roomIndex),
				"$eventType": event.Type,
			}
			if room.Ref != "" {
				subs["$roomId"] = fmt.Sprintf(".room_ref_%s", room.Ref)
			}
			if event.StateKey != nil {
				path = "/_matrix/client/r0/rooms/$roomId/state/$eventType/$stateKey"
				subs["$stateKey"] = *event.StateKey
			} else {
				path = "/_matrix/client/r0/rooms/$roomId/send/$eventType/$txnId"
				subs["$txnId"] = fmt.Sprintf("%d", eventIndex)
			}
			if event.Type == "m.room.member" && event.StateKey != nil &&
				event.Content != nil && event.Content["membership"] != nil {
				membership, ok := event.Content["membership"].(string)
				if ok {
					switch membership {
					case "join":
						path = "/_matrix/client/r0/join/$roomId"
						method = "POST"
						queryParams["server_name"] = fmt.Sprintf(".room_ref_%s_server_name", room.Ref)
					case "leave":
						path = "/_matrix/client/r0/rooms/$roomId/leave"
						method = "POST"
						if *event.StateKey != event.Sender {
							path = "/_matrix/client/r0/rooms/$roomId/kick"
							method = "POST"
							event.Content["user_id"] = *event.StateKey
						}
					case "invite":
						path = "/_matrix/client/r0/rooms/$roomId/invite"
						method = "POST"
						event.Content["user_id"] = *event.StateKey
					}
				}
			} else if event.Type == "m.room.canonical_alias" && event.StateKey != nil &&
				*event.StateKey == "" {
				alias, ok := event.Content["alias"].(string)
				if ok {
					ri := roomIndex
					instrs = append(instrs, instruction{
						method:        "PUT",
						path:          "/_matrix/client/r0/directory/room/" + url.PathEscape(alias),
						accessToken:   fmt.Sprintf("user_%s", event.Sender),
						substitutions: subs,
						queryParams:   queryParams,
						bodyFn: func(lk *sync.Map) interface{} {
							val, _ := lk.Load(fmt.Sprintf("room_%d", ri))
							return map[string]interface{}{
								"room_id": val,
							}
						},
					})
				}
			}
			instrs = append(instrs, instruction{
				method:        method,
				path:          path,
				body:          event.Content,
				accessToken:   fmt.Sprintf("user_%s", event.Sender),
				substitutions: subs,
				queryParams:   queryParams,
			})
		}
		sets[setIndex] = instrs
	}
	return sets
}
func calculateRoomInstructionSets ( r * Runner , hs b . Homeserver ) [ ] [ ] instruction { sets := make ( [ ] [ ] instruction , r . roomConcurrency ) for roomIndex , room := range hs . Rooms { setIndex := indexFor ( fmt . Sprintf ( " " , roomIndex ) , r . roomConcurrency ) instrs := sets [ setIndex ] var queryParams = make ( map [ string ] string ) if room . Creator != " " { storeRes := map [ string ] string { fmt . Sprintf ( " " , roomIndex ) : " " , } if room . Ref != " " { storeRes [ fmt . Sprintf ( " " , room . Ref ) ] = " " r . lookup . Store ( fmt . Sprintf ( " " , room . Ref ) , hs . Name ) } instrs = append ( instrs , instruction { method : " " , path : " " , accessToken : " " + room . Creator , body : room . CreateRoom , storeResponse : storeRes , } ) } else if room . Ref == " " { log . Printf ( " \n " , hs . Name , roomIndex ) return nil } for eventIndex , event := range room . Events { method := " " var path string subs := map [ string ] string { " " : fmt . Sprintf ( " " , roomIndex ) , " " : event . Type , } if room . Ref != " " { subs [ " " ] = fmt . Sprintf ( " " , room . Ref ) } if event . StateKey != nil { path = " " subs [ " " ] = * event . StateKey } else { path = " " subs [ " " ] = fmt . Sprintf ( " " , eventIndex ) } if event . Type == " " && event . StateKey != nil && event . Content != nil && event . Content [ " " ] != nil { membership , ok := event . Content [ " " ] . ( string ) if ok { switch membership { case " " : path = " " method = " " queryParams [ " " ] = fmt . Sprintf ( " " , room . Ref ) case " " : path = " " method = " " if * event . StateKey != event . Sender { path = " " method = " " event . Content [ " " ] = * event . StateKey } case " " : path = " " method = " " event . Content [ " " ] = * event . StateKey } } } else if event . Type == " " && event . StateKey != nil && * event . StateKey == " " { alias , ok := event . Content [ " " ] . ( string ) if ok { ri := roomIndex instrs = append ( instrs , instruction { method : " " , path : " " + url . PathEscape ( alias ) , accessToken : fmt . Sprintf ( " " , event . Sender ) , substitutions : subs , queryParams : queryParams , bodyFn : func ( lk * sync . Map ) interface { } { val , _ := lk . Load ( fmt . Sprintf ( " " , ri ) ) return map [ string ] interface { } { " " : val , } } , } ) } } instrs = append ( instrs , instruction { method : method , path : path , body : event . Content , accessToken : fmt . Sprintf ( " " , event . Sender ) , substitutions : subs , queryParams : queryParams , } ) } sets [ setIndex ] = instrs } return sets }
calculateRoomInstructionSets returns sets of HTTP requests to be executed in order.
calculateRoomInstructionSets returns sets of HTTP requests to be executed in order .
// add instructions to create rooms and send events // Store the homeserver's server_name, so that remote homeservers that attempt // to join this room know which server to contact // special cases: room joining, leaving and inviting // Set server_name to the homeserver that created the room, as they're a pretty // good candidate to join the room through // it's a kick // create the alias first then send the canonical alias // keep a ref to the current room index so it's correct when bodyFn is called