微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Cloudflare工人“单身”班

如何解决Cloudflare工人“单身”班

我已经开始在自己的网站上使用工作人员。在我的网站上工作人员的目的: 通常在HTML页面的不同位置注入一些代码(html / js / css)。 可以是一些配置数据,也可以是一些合法文本等。

所以我现在要做的是,在KV中为每个网站创建一个配置,并基于在html / js等之上注入的用户国家/语言。

下面是一个存储类(Singleton模式),它存储来自config的所有信息,但不适用于worker,因为它不起作用,我的意思是,在第一次请求后,数据是持久的,并且在一段时间后它会更新:

例如第一个请求网址:/about 根据第二个请求的URL:/es/about/

通过输出console.log(event.request)显示/es/about,但是Store.request输出/about/

为此的任何变通方法,以强制刷新数据,我认为是因为我不在构造函数中执行此操作,但是通过调用自定义方法应该可以解决问题,但事实并非如此。

下面是一些代码示例。


import { Store } from "@helpers/store";

addEventListener('fetch',event => {
    event.respondWith(handleRequest(event.request))
});

//HTML Rewriter Class
class Head {

    element(el) {
        el.append(`
                <script id="config">
                    var config = ${Store.export()};
                </script>`,{
            html: true
        });
    }
}

async function handleRequest(request) {
    let store = await Store.make(request);

    const response = await fetch(request);

    let html = new HTMLRewriter();
    html.on("head",new Head());

    return html.transform(response);
}

//src/helpers/store.js

class Store {

    constructor(){

        this._request = null
        this._config = {}
        this._url = null

    }

    async make(request){

        let config = {}

        this._request = request;

        const domain = this.url.hostname.replace(/www\./g,"");

        const country = request.headers.get('cf-ipcountry')

        const website = await WEBSITES.get(domain,"json"); //WEBSITES is KV namespace

        const { license,lang } = website;

        this._config = {
            country,domain,license,lang
        };

        return this;
    }

    export(){

        return JSON.stringify(this._config)
    }

    get request(){
        
        return this._request;

    }

    get url(){
        
        if(!this._url){

            this._url = new URL(this.request.url)

        }

        return this._url;

    }
}

export default new Store()

解决方法

您的Worker的单个实例可以处理多个请求,包括并发请求。在您的代码中,您正在使用Store的单例实例来存储有关当前请求的元数据。但是,如果同时处理多个请求,则第二个请求将在第一个请求完成之前覆盖Store的内容。这可能会导致第一个请求使用第二个请求中的元数据来呈现其HTML。

在这里似乎不需要使用单例模式。根据代码,您似乎真的想为每个请求创建一个单独的Store实例。

,

我想到了两个问题:

  • 您正在为对工作者的每次调用创建一个新的HTMLRewriter。这将导致一些并发问题。重写程序的实例化应在handleRequst方法之外进行。例如,在import语句之后。
  • 您正在导入Store类,并且从不实例化它,而是使用其方法,例如它们是静态的(不是)。这也会给您带来并发问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。