Repository: DiceDB/dice
File: internal/worker/worker.go (Go)

Code before:
			cmdList = append(cmdList, watchCmd)
			isWatchNotification = true

		case Unwatch:
			// Generate the Cmd being unwatched. All we need to do is remove the .UNWATCH suffix from the command and pass
			// it along as is.
			// Modify the command name to remove the .UNWATCH suffix, this will allow us to generate a consistent
			// fingerprint (which uses the command name without the suffix)
			diceDBCmd.Cmd = diceDBCmd.Cmd[:len(diceDBCmd.Cmd)-8]
			watchCmd := &cmd.DiceDBCmd{
				Cmd:  diceDBCmd.Cmd,
				Args: diceDBCmd.Args,
			}
			cmdList = append(cmdList, watchCmd)
			isWatchNotification = false
		}
	}

	// Unsubscribe Unwatch command type
	if meta.CmdType == Unwatch {
		command := cmdList[len(cmdList)-1]
		w.cmdWatchSubscriptionChan <- watchmanager.WatchSubscription{
			Subscribe:    false,
			WatchCmd:     command,
			AdhocReqChan: w.adhocReqChan,
			Fingerprint:  command.GetFingerprint(),
		}

		err := w.ioHandler.Write(ctx, "OK")
		if err != nil {
			return fmt.Errorf("error sending push response to client: %v", err)
		}
		return nil
	}

	// Scatter the broken-down commands to the appropriate shards.
	if err := w.scatter(ctx, cmdList); err != nil {
		return err
	}

	// Gather the responses from the shards and write them to the buffer.
	if err := w.gather(ctx, diceDBCmd, len(cmdList), isWatchNotification); err != nil {
		return err
	}

	if meta.CmdType == Watch {
		// Proceed to subscribe after successful execution
		w.cmdWatchSubscriptionChan <- watchmanager.WatchSubscription{
			Subscribe:    true,
			WatchCmd:     cmdList[len(cmdList)-1],
			AdhocReqChan: w.adhocReqChan,

Review comment (suggestion):
The UNWATCH command unsubscribes using the fingerprint and not the command. The usage is as follows:
```sh
> GET.WATCH k
1) GET
2) 12345 # Fingerprint
3) value
> GET.UNWATCH 12345
OK
```

Code after:
			}
			cmdList = append(cmdList, watchCmd)
			isWatchNotification = true

		case Unwatch:
			// Generate the Cmd being unwatched. All we need to do is remove the .UNWATCH suffix from the command and pass
			// it along as is.
			// Modify the command name to remove the .UNWATCH suffix, this will allow us to generate a consistent
			// fingerprint (which uses the command name without the suffix)
			diceDBCmd.Cmd = diceDBCmd.Cmd[:len(diceDBCmd.Cmd)-8]
			watchCmd := &cmd.DiceDBCmd{
				Cmd:  diceDBCmd.Cmd,
				Args: diceDBCmd.Args,
			}
			cmdList = append(cmdList, watchCmd)
			isWatchNotification = false
		}
	}

	// Unsubscribe Unwatch command type
	if meta.CmdType == Unwatch {
		// extract the fingerprint
		command := cmdList[len(cmdList)-1]
		fp, fperr := strconv.ParseUint(command.Args[0], 10, 32)
		if fperr != nil {
			err := w.ioHandler.Write(ctx, diceerrors.ErrInvalidFingerprint)
			if err != nil {
				return fmt.Errorf("error sending push response to client: %v", err)
			}
			return fperr
		}

		// send the unsubscribe request
		w.cmdWatchSubscriptionChan <- watchmanager.WatchSubscription{
			Subscribe:    false,
			AdhocReqChan: w.adhocReqChan,
			Fingerprint:  uint32(fp),
		}

		err := w.ioHandler.Write(ctx, "OK")
		if err != nil {
			return fmt.Errorf("error sending push response to client: %v", err)
		}
		return nil
	}

	// Scatter the broken-down commands to the appropriate shards.
	if err := w.scatter(ctx, cmdList); err != nil {
		return err
	}