ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Carabiner 1.0: Asset Management Library

January 28, 2009 9:23pm

Subscribe [19]
  • #31 / Aug 27, 2009 9:39am

    tonydewan

    100 posts

    I don’t know nearly enough about load balancing work to provide anything but pointers.  The filenames that Carabiner creates are a concatenation between the last-modified-time (filemtime in PHP) of the most recently modified file, and an MD5 hash of all of the asset filenames (in the group) put together.  I’m assuming, then, that the part of the filename that is different is the filemtime string, though I’m not necessarily sure why it would be different (unless your losing resource info when moving to the load balancing servers; at that point, filemtime would probably show as when the file was moved to the server.)  If that is indeed the problem, a simple (but not necessarily scalable) solution (assuming you’re on Unix) would be to run this command on whatever the most recently modified file is:

    touch -mt 0711171533 /PATH/TO/ASSETFILENAME.js

    where 0711171533 is a Unix timestamp.

    Otherwise, you’ll need to come up with a better way to create unique filenames, or store the filenames in a database.  In the case of the former, let me know if you come up with something.  In the case of the latter, I would store the MD5 hash as your key, and then when a new file is created, store that filemtime.  Then, every time a file is to be created, check for the hash, and if the filemtime is less than an hour (or whatever) older than the one you have, use the one from the DB.  Of course, that puts more load on the databse, which in the long run is not the best plan.

    If I come up with something better, I’ll let you know.

  • #32 / Aug 27, 2009 10:46am

    MindFeed

    9 posts

    Thanks for your thoughts into the problem. Though if I keep the file name same, the problem stands as it is. As each and every request has been distributed among 5 apache servers through load balancer, if LB hit the first server for getting the PHP->HTML page, it might hit any of 5 server for loading various resources like images, css, javascript. So in this case only first server has the combined/minified javascript/css files and not other servers and hence response will be 404 with the rest of 4 servers, unless and until LB hit that server for PHP->HTML page.

    Just preliminary thoughts towards solution:

    => Lets store the combined/minified version to DB, centrally accessible to all the servers.
    => Table will have four fields, asset_key, asset_type, asset_content, asset_dt
    => Store filename in asset_key (without extension, jst lastmodified + md5(filenames)), ‘js’ or ‘css’ in asset_type, combined and minified version to asset_content, and timestamp to asset_dt
    => In library we will check filename against asset_key in database instead of checking file on hard drive.
    => Modify _cache function to write into database instead of writing on disk
    => Modify _tag function where instead of including the combined/minified version of javascript/css from cache directory, will include path to controller/function which in turn read the database and echo the content with proper heading.
    => In that controller/function, I also can set proper caching header, after checking ETag and IF-Modified-Since

    howz that!

    Thanks,
    Bhargav Khatana

  • #33 / Aug 26, 2010 4:00am

    川红小霸王

    5 posts

    i hava a problem using this library, after set it up, when i run my proejct,it showed me an error “Message: Invalid argument supplied for foreach()”, how to fix the error?thanks…

  • #34 / Aug 26, 2010 10:58am

    tonydewan

    100 posts

    You’ll need to be much more specific about the error and your environment before I can help.

  • #35 / Aug 27, 2010 4:54am

    川红小霸王

    5 posts

    Thanks for reply,Tony.

    Actually the error is no longer existing, but my css file still dosent work, and im quite sure my setting is correct. So i just wonder when i add a css file into my view, is that mean

    <?php $this->carabiner->css('basic.css'); ?>
    can take place of
    <link href="/assets/styles/basic.css" rel="stylesheet" type="text/css" />

    ?

  • #36 / Aug 27, 2010 5:04am

    川红小霸王

    5 posts

    Im using your config file with default setting.Here is my root project structure.

    |-assets
      |—styles
      |—scripts
      |—cache
    |-image
    |-system
    index.php

    I put all my css files into styles folder and all js files into scripts.

  • #37 / Aug 27, 2010 8:33pm

    tonydewan

    100 posts

    You still need to do this in your view:

    $this->carabiner->display('css');

    This goes in your controller, not your view.

    $this->carabiner->css('basic.css');
  • #38 / Aug 27, 2010 11:37pm

    川红小霸王

    5 posts

    Thanks Tony, i will give it a try 😊

  • #39 / Aug 29, 2010 12:53am

    川红小霸王

    5 posts

    i tried out this morning, it works perfect when i used two lines to load my css file

    $this->carabiner->css('basic.css');
    $this->carabiner->css('home.css');

    but when i load them togerther using

    $this->carabiner->css( array('basic.css', 'home.css') );

    my cache file only showed me part of my css file.

  • #40 / Sep 11, 2010 8:35am

    Olof Larsson

    1 posts

    Hello! Great system thank you! 😊
    I am using version 1.45. Here is a solution to a bug.

    The bug:
    In one of my views i have the following code:

    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Title</title>
        <?php $this->carabiner->display('my_default_group'); ?>
        <?php $this->carabiner->display(); ?>
    </head>
    
    ...

    Some times I add assets to the main group but sometimes I do not.
    When I do not the system fails and outputs a non-existing file in the header.

    The Solution:
    Take a look at this code segment from a non modified version 1.45

    private function _display_js($group = 'main')
        {
            if( empty($this->js) ) return; // if there aren't any js files, just stop!
            if( !isset($this->js[$group]) ): // the group you asked for doesn't exist. This should never happen, but better to be safe than sorry.
    
                log_message('error', "Carabiner: The JavaScript asset group named '{$group}' does not exist.");
                return;
            
            endif;
        
        ...

    Both of the if-statements will pass. That is bad.

    change from:

    if( empty($this->js) ) return; // if there aren't any js files, just stop!

    to

    if( isset($this->js[$group]) && empty($this->js[$group]) ) return; // if there aren't any js files, just stop!

    The same goes for the css function:

    change from:

    if( empty($this->css) ) return; // there aren't any css assets, so just stop!

    to

    if( isset($this->css[$group]) && empty($this->css[$group]) ) return; // there aren't any css assets, so just stop!


    By the way: I would like to help you improve this library more directly. Is this in a repository somewhere I could get access to?

  • #41 / Aug 22, 2012 11:09am

    Riddler

    1 posts

    HI Great System ! Exactly what i was looking for ! 😊 .. i am sorry if this sounds like a rather simple question but i still cant get it to load my images into the “View” ... is there a way or syntax to that, if yes please let me know.

    Thanks in advance.

    my directory structure is somewhat like this:

    |-application
    |-system
    |-assets
      |-images
      |-css
      |-js

  • #42 / Nov 09, 2012 9:20am

    slowgary

    654 posts

    tonydewan,

    Thanks for contributing a very useful library to the CodeIgniter project.  I know this thread is a little old, but I stumbled on it while looking for something else and I think it will be very useful to me.

    I have a few questions for you though.  I’ve had great success using MD5 for caching assets in my project, but they’re all images… nothing for CSS/JS yet.  I’ve always resorted to md5()‘ing the contents of the file, that way only changes to the actual contents cause the cache to invalidate.  In the case of Carabiner, might that solve the problem of not functioning in a load balanced setup?  I assume the issue with a load balancing is that the modified dates of the files differ across servers, so the filenames differ as well.

    Secondly, does Carabiner have to recreate the hash each time?  This is somewhat related to the first question… my image assets are actually renamed as md5(file_get_contents(’/path/to/image.jpg’)), and then I store a reference to the image in the database so that I don’t have to md5() the contents ever again.  For the purposes of CSS / JS, since you actually want to retain the originals as their original filenames, it seems that you’d need to calculate the hashed filename on every request.  If that’s the case, hashing the contents seems like too much overhead.

    For a layperson like myself, can you provide a very high level overview of what happens when using Carabiner on the first request as well as subsequent requests?  Or maybe you can just confirm my assumptions below?

    =================================

    Assumptions

    On each request, Carabiner takes all of the assets that have been passed to it, determines a cached filename for the group of files, and checks to see if that file exists in the cache directory.

    If the file does not exist, Carabiner combines the contents of all the files, minifies the contents, and writes it to the filename that it initially checked.

    If the file does exist, no combining or minifying is necessary, Carabiner’s work is done.

    =================================

    If these assumptions are true… how would my view obtain the cached filename?  It seems also that Carabiner would have to do a few stat system calls on every request.  I know these are cached, but can you speak to the efficiency of doing this?  I’m ultra performance minded.

    I’d like to incorporate Carabiner into a current project, but I really want to understand it before making a decision.  Based on the grammatical clarity of your posts, I already expect the library to be of good quality.  One can usually make some assumptions of code quality based on the writer’s written language quality.

    I really appreciate your efforts and any answers you might provide.

    Thanks!

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases