不完全确定你的栈是什么标签elixir和红宝石,但一个解决方案将使用Agent模块。另一种解决方案是使用ETS/DETS Table
这本质上是一个GenServer封装状态,并且对于这样的事情是完美的。
基本上,根据您的堆栈,您将向运行代理的elixir/phoenix应用程序发送消息。
例如:
#lib/appname.ex
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
worker(AppName.ClickCounter.start_link, [])
]
opts = [strategy: :one_for_one, name: Test.Supervisor]
Supervisor.start_link(children, opts)
end
上面开始一旦应用程序启动并在的故障或崩溃将重新启动该代理的事件的代理。
然后你MyApp.ClickCounter
模块:
defmodule MyApp.ClickCounter do
@doc """
Starts the Agent and registers it's process id under the name of the module name. Initializes it's state as an empty map.
"""
def start_link do
Agent.start_link(fn -> %{} end, name: __MODULE__)
end
@doc """
Takes in a string url and increments it's click count by one.
If there is no counter for the url already it will create one with a default value of 0.
"""
def increment_counter(url), do: update_state(url)
@doc """
Returns the current value of the counter for the given url
"""
def get_counter(url), do: Agent.get(__MODULE__, &(Map.fetch!(&1, url)))
defp update_state(value) do
Agent.update(__MODULE__, fn(state) ->
Map.update(state, value, 1, fn(count) ->
count + 1
end)
end)
end
end
那么火了iex -S mix
控制台和与它一出戏。
iex(1)> MyApp.ClickCounter.increment_counter("http://google.com/123")
:ok
iex(2)> MyApp.ClickCounter.get_counter("http://google.com/123")
1
iex(3)> MyApp.ClickCounter.increment_counter("http://google.com/123")
:ok
iex(4)> MyApp.ClickCounter.increment_counter("http://google.com/123")
:ok
iex(5)> MyApp.ClickCounter.increment_counter("http://google.com/123")
:ok
iex(6)> MyApp.ClickCounter.get_counter("http://google.com/123")
4
正如你可以从上面看到的,你可以将任何你想要的逻辑应用到更新检索方法中。由于它存储在一个进程中,所以它非常快速。
如果这需要持久化,您可以使用类似ETS/DETS的东西,它可以将表持久保存到磁盘,并在重新启动/崩溃时加载现有数据。
另一种方式持续下去可能是有一个数据库,然后有一个过程的工人(简单的方法是使用GenServer
,并将它落实Process.send_after(x,x, 1000ms)
之类的事情),它通过了国家去,并再次持续到数据库允许您从崩溃中恢复。
您需要将数据保存在服务器上的某个位置,最好的方法是使用某种数据库。这真的没有办法。 – tadman
@tadman如何保存每个新的网址(m1234),然后有一个计数列的网址? – arpit
这是一个解决方案,但它需要一个数据库来存储这些计数。如果你想要便宜又简单的东西,请使用[Redis](http://redis.io)作为后端。这样,如果这些应该在一段时间后过期,您可以设置一个TTL。 – tadman