Load Balancing Server Based on Time Allowing All Operations

Hi there,
I am trying to develop a solution using Cloudflare workers that enables me to route my traffic to my server based on time and that allows post, get and other requests to my servers, this has been partially solved here, but I am not able to route my post and get requests and to appropriate files.
LINK TO THREAD : Do a time based redirect in cloudflare workers? - #4 by signalnerve
For eg-
SERVER A; 12 AM-12PM
SERVER B; 12 PM-12AM
If a request is made to get.com/p.css (A GET REQUEST) it should be served from SERVER A at time 2 am.
Similarly a POST Request to form.php (A POST REQUEST) it should be served from SERVER B at time 2 pm.
And I want this to be done dynamically as I have thousands of files. It can utilize the request method parameters.
Hoping for a Prompt Response !!

MY WORKERS CODE
addEventListener(‘fetch’, event => {
/**
* In the event of an uncaught exception, fail open as if the worker did not exist
* If you’re not sure what you’re doing, it’s recommended you include this call
* as the very first thing your worker does in its fetch event listener
*
* If you do not include this call, but your worker encounters an uncaught exception
* while processing your request, your user will see an edge-level error page
* instead of a response from your site, app or API
*
* Read on below for more info on deciding whether to
* fail open or fail closed in your workers
*/
event.passThroughOnException();

//This allows you to return your own Response object from your worker
event.respondWith(route(event));

});
addEventListener(‘fetch’, event => {
event.respondWith(handleRequest(event.request))
})
const Method = method => req =>
req.method.toLowerCase() === method.toLowerCase()
const Connect = Method(‘connect’)
const Delete = Method(‘delete’)
const Get = Method(‘get’)
const Head = Method(‘head’)
const Options = Method(‘options’)
const Patch = Method(‘patch’)
const Post = Method(‘post’)
const Put = Method(‘put’)
const Trace = Method(‘trace’)

const Header = (header, val) => req => req.headers.get(header) === val
const Host = host => Header(‘host’, host.toLowerCase())
const Referrer = host => Header(‘referrer’, host.toLowerCase())

const Path = regExp => req => {
const url1 = “https://ag-1.com”
const url2 = “https://ag-2.com”

// If no timezone is needed, just use a plain UTC date
// const date = new Date()

// If a timezone is needed, use toLocaleString and pass a timeZone option
const date = new Date().toLocaleString(“en-US”, {timeZone: “Asia/Colombo”})

// Coerce the date string with correct timezone back into a date
const hour = new Date(date).getHours()

const url = hour < 12 ? url1 : url2
const path = url.pathname
const match = path.match(regExp) ||
return match[0] === path
}

/**

  • The Router handles determines which handler is matched given the

  • conditions present for each request.
    */
    class Router {
    constructor() {
    this.routes =
    }

    handle(conditions, handler) {
    this.routes.push({
    conditions,
    handler,
    })
    return this
    }

    connect(url, handler) {
    return this.handle([Connect, Path(url)], handler)
    }

    delete(url, handler) {
    return this.handle([Delete, Path(url)], handler)
    }

    get(url, handler) {
    return this.handle([Get, Path(url)], handler)
    }

    head(url, handler) {
    return this.handle([Head, Path(url)], handler)
    }

    options(url, handler) {
    return this.handle([Options, Path(url)], handler)
    }

    patch(url, handler) {
    return this.handle([Patch, Path(url)], handler)
    }

    post(url, handler) {
    return this.handle([Post, Path(url)], handler)
    }

    put(url, handler) {
    return this.handle([Put, Path(url)], handler)
    }

    trace(url, handler) {
    return this.handle([Trace, Path(url)], handler)
    }

    all(handler) {
    return this.handle(, handler)
    }

    route(req) {
    const route = this.resolve(req)

     if (route) {
         return route.handler(req)
     }
    
     return new Response('resource not found', {
         status: 404,
         statusText: 'not found',
         headers: {
             'content-type': 'text/plain',
         },
     })
    

    }

    /**

    • resolve returns the matching route for a request that returns

    • true for all conditions (if any).
      */
      resolve(req) {
      return this.routes.find(r => {
      if (!r.conditions || (Array.isArray(r) && !r.conditions.length)) {
      return true
      }

       if (typeof r.conditions === 'function') {
           return r.conditions(req)
       }
      
       return r.conditions.every(c => c(req))
      

      })
      }
      }
      /**

  • Example of how router can be used in an application

  • */

async function handleRequest(request) {
const r = new Router()
// Replace with the approriate paths and handlers
r.post(‘/‘, req => fetch(req)) // return the response from the origin
r.get(’/
’, req => fetch(req)) // return the response from the origin

const resp = await r.route(request)
return resp

}

1 Like

@aayush23467, it looks like you haven’t updated the routes at the end of the code sample you shared. In your example, you should have something like:

r.get('/p.css', req => fetch(req))
r.post('/form.php', req => fetch(req))

Note that you’ll also need to update the fetch(req) part of each of those into a fetch request to whatever server you’d like it to go to – as we discussed in the other thread, you’ll want to do something like fetch("https://server_a").