3 Remote Procedure Calls

Remote Procedure Call Protocol (RPC)

  • Call a remote function to get data, have them compute for you
  • In typical RPC, client waits for server's response before continuing, making it inherently synchronous (block until finish)
  • Pros:
    • Modularity
    • Scalable
    • Programming language independence
    • Offload expensive functions to powerful servers

Stubs in RPC

  • helper that makes remote function calls look like local calls
  • Then, RPC Runtime passes encoded data over the network to server

RPC Workflow

  1. Client stub sends request
  2. RPC runtime encodes (serialize) data
  3. send to server
  4. Server RPC continually listens for messages, receives it
  5. Server's dispatch code receives and decodes data
  6. Server compute
  7. Serialize & send it back

Serialization

Converting in-memory data (like a Go struct) into transferable format; Deserialization: rebuilding it back

// GetWeatherData fetches the temperature reading for a given weather station ID over RPC
func GetWeatherData(client *rpc.Client, id int) (float64, error) {
	req := TemperatureRequest{StationID: strconv.Itoa(id)}
	var resp TemperatureResponse
	if err := client.Call("WeatherService.GetTemperature", req, &resp); err != nil {
		return math.NaN(), err
	}

	return resp.Temperature, nil
}

// Test GetWeatherData implementation
func main() {
	// Connect to the RPC server
	client, err := rpc.Dial("tcp", "localhost:8080")
	if err != nil {
		log.Fatal("Error connecting to RPC server:", err)
	}
	defer client.Close()

	// Fetch weather data for station ID 1
	temp, err := GetWeatherData(client, 1)
	if err != nil {
		log.Fatal("Error fetching weather data:", err)
	}

	log.Println("Temperature:", temp)
}