2016-12-01 88 views
0

我有很多网址。我需要与一些人分享这些网址。 我需要将这些网址转换为新的网址,例如:=> 5次点击每个网址后,它们应该重定向到登录页面。点击次数后重定向

例如www.abc.com/m =>www.abc.com/m1234(这是我们分享的)=> 5次点击后=>登录页面。

注意:www.abc.com/m需要登录。 www.abc.com/m1234不需要登录尝试5次,它会打开www.abc.com/m

我需要用elixir/ruby​​来解决这个问题。 有没有办法做到这一点,而不包括数据库?

什么是最好的方法呢?

+0

您需要将数据保存在服务器上的某个位置,最好的方法是使用某种数据库。这真的没有办法。 – tadman

+0

@tadman如何保存每个新的网址(m1234),然后有一个计数列的网址? – arpit

+0

这是一个解决方案,但它需要一个数据库来存储这些计数。如果你想要便宜又简单的东西,请使用[Redis](http://redis.io)作为后端。这样,如果这些应该在一段时间后过期,您可以设置一个TTL。 – tadman

回答

1

不完全确定你的栈是什么标签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)之类的事情),它通过了国家去,并再次持续到数据库允许您从崩溃中恢复。