All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zio.redis.api.Cluster.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2021 John A. De Goes and the ZIO contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package zio.redis.api

import zio.Chunk
import zio.redis.Input._
import zio.redis.Output.{ChunkOutput, ClusterPartitionOutput, UnitOutput}
import zio.redis.api.Cluster.{ClusterSetSlots, ClusterSlots, askingCommand}
import zio.redis.internal.{RedisCommand, RedisEnvironment}
import zio.redis.options.Cluster.SetSlotSubCommand._
import zio.redis.options.Cluster.{Partition, Slot}

trait Cluster[G[+_]] extends RedisEnvironment[G] {

  /**
   * When a cluster client receives an -ASK redirect, the ASKING command is sent to the target node followed by the
   * command which was redirected.
   *
   * @return
   *   the Unit value.
   */
  final def asking: G[Unit] =
    askingCommand.run(())

  /**
   * Set a hash slot in importing state. Command should be executed on the node where hash slot will be migrated
   * (destination node)
   *
   * @param slot
   *   hash slot that will be set in importing state
   * @param nodeId
   *   the source node Id from which hash slot will be imported
   * @return
   *   the Unit value.
   */
  final def setSlotImporting(slot: Slot, nodeId: String): G[Unit] = {
    val command = RedisCommand(
      ClusterSetSlots,
      Tuple3(LongInput, ArbitraryValueInput[String](), ArbitraryValueInput[String]()),
      UnitOutput
    )
    command.run((slot.number, Importing.asString, nodeId))
  }

  /**
   * Set a hash slot in migrating state. Command should be executed on the node from which hash slot will be imported
   * (source node)
   *
   * @param slot
   *   hash slot that will be set in migrating state
   * @param nodeId
   *   the destination node Id where slot will be migrated
   * @return
   *   the Unit value.
   */
  final def setSlotMigrating(slot: Slot, nodeId: String): G[Unit] = {
    val command = RedisCommand(
      ClusterSetSlots,
      Tuple3(LongInput, ArbitraryValueInput[String](), ArbitraryValueInput[String]()),
      UnitOutput
    )
    command.run((slot.number, Migrating.asString, nodeId))
  }

  /**
   * Bind the hash slot to a different node. It associates the hash slot with the specified node, however the command
   * works only in specific situations and has different side effects depending on the slot state.
   *
   * @param slot
   *   hash slot that will be bind
   * @param nodeId
   *   the destination node Id where slot have been migrated
   * @return
   *   the Unit value.
   */
  final def setSlotNode(slot: Slot, nodeId: String): G[Unit] = {
    val command = RedisCommand(
      ClusterSetSlots,
      Tuple3(LongInput, ArbitraryValueInput[String](), ArbitraryValueInput[String]()),
      UnitOutput
    )
    command.run((slot.number, Node.asString, nodeId))
  }

  /**
   * Clear any importing / migrating state from hash slot.
   *
   * @param slot
   *   hash slot that will be cleared
   * @return
   *   the Unit value.
   */
  final def setSlotStable(slot: Slot): G[Unit] = {
    val command =
      RedisCommand(ClusterSetSlots, Tuple2(LongInput, ArbitraryValueInput[String]()), UnitOutput)
    command.run((slot.number, Stable.asString))
  }

  /**
   * Returns details about which cluster slots map to which Redis instances.
   *
   * @return
   *   details about which cluster
   */
  final def slots: G[Chunk[Partition]] = {
    val command = RedisCommand(ClusterSlots, NoInput, ChunkOutput(ClusterPartitionOutput))
    command.run(())
  }
}

private[redis] object Cluster {
  final val Asking          = "ASKING"
  final val ClusterSetSlots = "CLUSTER SETSLOT"
  final val ClusterSlots    = "CLUSTER SLOTS"

  final val askingCommand: RedisCommand[Unit, Unit] =
    RedisCommand(Asking, NoInput, UnitOutput)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy