Git Product home page Git Product logo

cfml-weighted-round-robin's Introduction

Weighted Round Robin

This module provides a round-robin algorithm for rotating elements according to differing weights, instead of evenly. It was inspired by the npm package weighted-round-robin, and uses the same logic for its algorithm.

Usage

The module tracks elements that you wish to distribute in a weighted round-robin rotation. They're added to the rotation as a struct that, at minimum, contains an id key with a unique identifier (though you'll probably also want to include a weight). If you like, the struct can contain other keys - a name for example.

It stores these elements, either in memory or in a cache, and returns the element struct when you call the module's get() method. These elements will be rotated and returned, according to their weight. Here's an example:

rr = new path.to.weightedroundrobin.RoundRobin();

rr.add(
  {
    "id": "heavy",
    "weight": 6
  }
);

rr.add(
  {
    "id": "light",
    "weight": 3
  }
);

rr.add(
  {
    "id": "feather",
    "weight": 1
  }
);

// you can add as many as needed

for ( i = 0; i < 10; i++ ) {
  writeOutput( rr.get().id & '<br>' );
}
// heavy, light, heavy, heavy, light, heavy, feather, heavy, heavy, light

Using Memory or a Cache

By default this component stores the round-robin rotation in memory; it is init without any arguments and you should store it as a singleton (or in the application scope).

However, when you're deploying a distributed application (like Docker Swarm), or if you'd like more robust data persistence, you can configure the module to store/track the rotating elements in a remote cache (like Redis). Note that remote caching engines are only available in Lucee or Adobe ColdFusion 2018.

To use this approach, init the component with a cache identifier you'd like the component to use for storing/retrieving the data and the name of the cache region it should use (this defaults to object). For example:

rr = new path.to.weightedroundrobin.RoundRobin( 
  cacheId = '_roundrobinElements',
  cacheRegion = 'cache_region_name'
);

When using this approach, you don't necessarily need to store the RoundRobin component in a persistant scope, since the data is tracked/stored separately.

Reference Manual

init( string cacheId = '', string cacheRegion = 'object' )

When the component is init with a cacheId and cacheRegion, the data will be stored in the specified cache, using the provided cacheId, instead of in the component memory, which is the default.

add( required struct element, boolean overwrite = true )

Adds an element to the round-robin rotation. Returns the element's key.

The element is a struct, with at minimum an id key, but if you're using this module, you'll likely also want a weight key. The default weight is 1, which will be used if no weight is provided.

By default, if you try to add() an element that already exists, it is ignored. If you want to overwrite the existing element, set the overwrite parameter to true.

get()

Returns the next element in the round-robin rotation. The full struct is returned.

remove( required any key )

Removes an element from the round-robin rotation.

reset()

Restores all elements in the round-robin rotation to their original weight, effectively restarting the rotation.

wipe()

Removes all elements from the rotation, leaving it empty.

expose()

Returns the round-robin rotation struct so you can see elements and their weights. Helpful for debugging.

size()

Returns the number of elements being tracked in the rotation.

hasCache()

Returns true or false, depending on if the component is using a cache for storing the data or not.

Questions

For questions that aren't about bugs, feel free to hit me up on the CFML Slack Channel; I'm @mjclemente. You'll likely get a much faster response than creating an issue here.

Contributing

๐Ÿ‘๐ŸŽ‰ First off, thanks for taking the time to contribute! ๐ŸŽ‰๐Ÿ‘

Before putting the work into creating a PR, I'd appreciate it if you opened an issue. That way we can discuss the best way to implement changes/features, before work is done.

Changes should be submitted as Pull Requests on the develop branch.

cfml-weighted-round-robin's People

Contributors

mjclemente avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.