Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto delete key from Deno.openKv() at a specific time or after a time; #19453

Closed
alaminkouser opened this issue Jun 10, 2023 · 3 comments
Closed

Comments

@alaminkouser
Copy link

I am lucky to get early access to Deno.openKv() in Deno Deploy. I was just playing with it. I made a very simple function which redirects users to a url.

How it works/How to use it:
Deploy url is: https://307.deno.dev
If a user want to create a redirect url then he needs to add desired url in the path of the url.
Example 1: https://307.deno.dev/{target_url}
Example 2: https://307.deno.dev/https://example.com

User will get a url in response. If any user opens that url then it will redirect to targeted url.

This is my deploy code:

const kv = await Deno.openKv();

async function main(
  reqEvt: Deno.RequestEvent,
): Promise<Response> {
  const _kv: Deno.KvEntry<unknown>[] = [];
  for await (const entry of kv.list({ prefix: ["307"] })) {
    if (parseInt(entry.key[2].toString()) + 86400000 < Date.now()) {
      kv.delete(entry.key);
    } else {
      _kv.push(entry);
    }
  }
  if (new URL(reqEvt.request.url).pathname === "/") {
    return new Response("GUIDE");
  } else {
    const path = new URL(reqEvt.request.url).pathname.slice(1) +
      new URL(reqEvt.request.url).search;

    if (isURL(path) === true) {
      const id = crypto.randomUUID().replaceAll("-", "");
      await kv.set(["307", id, Date.now()], path);
      return new Response("http://307.deno.dev/" + id);
    } else {
      let redirectURL = "";
      _kv.forEach((entry) => {
        if(entry.key[1] === path) {
          redirectURL = entry.value as string;
        }
      });
      if (redirectURL !== "") {
        return Response.redirect(redirectURL, 307);
      } else {
        return Response.redirect("https://307.deno.dev/", 307);
      }
    }
  }
}

function isURL(url: string): boolean {
  if (!/^https?:\/\//.test(url)) {
    return false;
  }
  if (/[^a-zA-Z0-9-._~:/?#=]/.test(url)) {
    return false;
  }
  return true;
}

async function handle(conn: Deno.Conn) {
  try {
    for await (const requestEvent of Deno.serveHttp(conn)) {
      await requestEvent.respondWith(
        main(requestEvent),
      );
    }
  } catch (error) {
    console.log(error);
  }
}

const server = Deno.listen({
  port: 8000,
});

for await (const conn of server) {
  handle(conn);
}

I want to keep the key for 1 day. Then the key will expire. But Now I have to add timestamp in each key. And I have to loop through all keys then delete keys that are older than 1 day.

Can openKv perform auto deletion of keys based on time or after a certain time?

@csvn
Copy link

csvn commented Jun 20, 2023

I've been interested also in the possibility to set an "experitation time" for data stored. Since clearing out expired data is a background job, it does not feel like the right fit to clear out data when performing other requests.

If there were some way to run background tasks, I would be fine with not having an explicit API for how long data should last before auto-deletion, though it would still be a neat feature to support it in KV directly.

@jwenjian
Copy link

jwenjian commented Aug 3, 2023

+1 for this feature.

I was planning to migrate my visitor-badge service to deno deploy and kv, but I did not find similar data expiring strategy, so I just setup a deno deployment and make it works for me only, like below badge:

Sample code for visitor badge in deno: https://github.com/jwenjian/visitor-badge-deno

@csvn
Copy link

csvn commented Aug 22, 2023

I believe this issue is solved by #20091, released in Deno v1.36.2. It adds a expireIn option (ms) to the set method for Deno KV.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants