How to update a function's value once it's been called in golang

huangapple go评论98阅读模式
英文:

How to update a function's value once it's been called in golang

问题

我正在处理一个系统,在该系统中,我必须限制来自特定IP的并发连接。一旦建立连接,会执行一些步骤,然后将其关闭,以便可以建立其他连接。下面是我正在更新特定变量值的代码。

代码链接 - http://tpcg.io/_SQZEEX

package main

import "fmt"

var addresses = make([]string, 0)

func count(rAddr string, slice *[]string) map[string]int {
    dict := make(map[string]int)
    *slice = append(*slice, rAddr)
    for _, a := range *slice {
        dict[a]++
    }
    return dict
}

func listen() int {
    var rAddr string
    rAddr = "1.1.1.2"
    number_of_addresses := count(rAddr, &addresses)
    var v int
    for k, v := range number_of_addresses {
        fmt.Println(k, "value is", v)
        if v > 0 {
            v--
            fmt.Println(k, "decreased value is", v)
        }
    }
    return v
}

func main() {
    listen()
    listen()
}

在再次调用函数时,"v"变量的值没有刷新,输出如下:

1.1.1.2 value is 1
1.1.1.2 decreased value is 0
1.1.1.2 value is 2
1.1.1.2 decreased value is 1

期望的输出是:

1.1.1.2 value is 1
1.1.1.2 decreased value is 0
1.1.1.2 value is 1
1.1.1.2 decreased value is 0

我应该怎么做才能在每次减少值时更新它?我理解值是刷新的,但没有发送回count函数。如何实现这一点?

英文:

I am working on a system where I have to limit concurrent connections from a particular IP. Once a connection is made, some steps are performed and then it is dropped so that other connections can be made. Below is the code where I am updating the value of a particular variable.

Link for code - http://tpcg.io/_SQZEEX

package main

import "fmt"


var addresses = make([]string, 0)
func count(rAddr string, slice *[]string) map[string]int {
    dict := make(map[string]int)
    *slice = append(*slice, rAddr)
    for _, a := range *slice {
    dict[a]++

    }
    return dict
}

func listen() int {

    var rAddr string
    rAddr = "1.1.1.2"
    number_of_addresses:=count(rAddr ,&addresses)
    var v int
    for k, v := range number_of_addresses {

    fmt.Println(k, "value is", v)

        if (v > 0) {
            v--
            fmt.Println(k, "decreased value is", v)
        }


    }
    return v
}


func main() {

    listen()
    listen()

}

Upon calling the function again, the values are not refreshing for the "v" variable and the output is as below

1.1.1.2 value is 1
1.1.1.2 decreased value is 0
1.1.1.2 value is 2
1.1.1.2 decreased value is 1

Expected output:

1.1.1.2 value is 1
1.1.1.2 decreased value is 0
1.1.1.2 value is 1
1.1.1.2 decreased value is 0

What could I do so that the value is updated each time it is decreased. I understand that the value is refreshed but not sent back to the count function. How can this be achieved

答案1

得分: 1

根据我的评论,重构代码以通过map来跟踪IP地址,即使用map[string]int来跟踪使用情况。

以下是一个基本的实现示例:

// 通过map来跟踪唯一的地址:
// - 键:IP地址的字符串形式
// - 值:使用计数
var (
    usageMap = make(map[string]int) //
    l        sync.Mutex             // 确保对map的并发访问是同步的
)

func modifyAddr(addr string, delta int) int {
    l.Lock()
    defer l.Unlock()

    usageMap[addr] += delta

    return usageMap[addr]
}

func incAddr(addr string) int { return modifyAddr(addr, 1) }
func decAddr(addr string) int { return modifyAddr(addr, -1) }

使用示例:

const maxConcurrentUsage = 20

func listen() {

    rAddr := "1.1.1.2"

    usage := incAddr(rAddr)
    defer decAddr(rAddr)

    if usage > maxConcurrentUsage {
        log.Printf("超过最大并发使用量(%d)的地址:%q", maxConcurrentUsage, rAddr)
        return
    }

    // 处理逻辑放在这里
}

你可以在以下链接中查看代码的运行示例:https://go.dev/play/p/Jvx8l4F9OE8

英文:

Per my comments, refactor to track IP addresses via a map i.e. a map[string]int to track usage.

A basic implementation to get you started:

// track unique addresses via a map:
// - key:   string of the IP address
// - value: usage count
var (
	usageMap = make(map[string]int) //
	l        sync.Mutex             // ensure concurrent access to map is synchronized
)

func modifyAddr(addr string, delta int) int {
	l.Lock()
	defer l.Unlock()

	usageMap[addr] += delta

	return usageMap[addr]
}

func incAddr(addr string) int { return modifyAddr(addr, 1) }
func decAddr(addr string) int { return modifyAddr(addr, -1) }

and to use:

const maxConcurrentUsage = 20

func listen() {

	rAddr := "1.1.1.2"

	usage := incAddr(rAddr)
	defer decAddr(rAddr)

	if usage > maxConcurrentUsage {
		log.Printf("maximum concurrent usage exceeded (%d) for address: %q", maxConcurrentUsage, rAddr)
		return
	}

    // handler logic goes here
}

https://go.dev/play/p/Jvx8l4F9OE8

huangapple
  • 本文由 发表于 2022年9月22日 01:40:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/73804920.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定