)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":455,"name":"Stuart McLaren","email":"stuart.mclaren@hpe.com","username":"stuart-mclaren"},"change_message_id":"cb4e0300b154a38b8564e6eb5d1452de35f5b4d3","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Stop concurrent backend fetches on the same image"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Simultaneous requests for the same (not cached) image will only write the"},{"line_number":10,"context_line":"image to the cache once, reducing the stress on the backend."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I98f006c4fe1b063d1514fbf32a617607c5dabea5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"AAAAS3%2F%2Fu3Y%3D","line":10,"updated":"2013-09-20 12:25:02.000000000","message":"Tom, I think a little more verbiage here would help reviewers understand the motivation for this change.\n\nMy understanding is that there are two efficiency gains here:\n\n1) Currently N simultaneous images downloads for the same image will fetch the image\n    N times from the backend\n\nThis patch ensures that in this case the image is fetched only once from the backend, reducing network usage.\n\n2) Currently N simultaneous images downloads for the same image will write the image\n    data to the cache N times\n\nThis patch ensures that in this case the image is written only once to cache, reducing disk usage.\n\nYour comment essentially says this, but as I say, a little more verbosity may help reviewers.","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"de2ac5fee2ceaef8aed9a6b42d04e0d3dbca2c89","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Stop concurrent backend fetches on the same image"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Simultaneous requests for the same (not cached) image will only write the"},{"line_number":10,"context_line":"image to the cache once, reducing the stress on the backend."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I98f006c4fe1b063d1514fbf32a617607c5dabea5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"AAAAS3%2F%2Fu1E%3D","line":10,"in_reply_to":"AAAAS3%2F%2Fu3Y%3D","updated":"2013-09-20 12:37:59.000000000","message":"Will do","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"}],"etc/glance-api.conf":[{"author":{"_account_id":6549,"name":"Zhi Yan Liu","email":"lzy.dev@gmail.com","username":"lzy-dev"},"change_message_id":"eb9aa24a3a6f55ab0ae48c19207c861a88f5200f","unresolved":false,"context_lines":[{"line_number":106,"context_line":"# Directory to use for lock files. Default to a temp directory"},{"line_number":107,"context_line":"# (string value). This setting needs to be the same for both"},{"line_number":108,"context_line":"# glance-scrubber and glance-api."},{"line_number":109,"context_line":"#lock_path\u003d\u003cNone\u003e"},{"line_number":110,"context_line":"lock_path\u003d/tmp"},{"line_number":111,"context_line":"#"},{"line_number":112,"context_line":"# Property Protections config file"}],"source_content_type":"text/plain","patch_set":5,"id":"AAAATH%2F%2FzoE%3D","line":109,"updated":"2013-10-09 15:28:24.000000000","message":"remove this useless line please.","commit_id":"711041b7e3ba5259df96a7078124796d9ae28a3c"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"ea9aafd509435366c9659e505b38615f989e886b","unresolved":false,"context_lines":[{"line_number":106,"context_line":"# Directory to use for lock files. Default to a temp directory"},{"line_number":107,"context_line":"# (string value). This setting needs to be the same for both"},{"line_number":108,"context_line":"# glance-scrubber and glance-api."},{"line_number":109,"context_line":"#lock_path\u003d\u003cNone\u003e"},{"line_number":110,"context_line":"lock_path\u003d/tmp"},{"line_number":111,"context_line":"#"},{"line_number":112,"context_line":"# Property Protections config file"}],"source_content_type":"text/plain","patch_set":5,"id":"AAAATH%2F%2FzgE%3D","line":109,"in_reply_to":"AAAATH%2F%2FzoE%3D","updated":"2013-10-09 15:39:54.000000000","message":"Sorry, that was there from my testing.","commit_id":"711041b7e3ba5259df96a7078124796d9ae28a3c"}],"etc/glance-scrubber.conf":[{"author":{"_account_id":6549,"name":"Zhi Yan Liu","email":"lzy.dev@gmail.com","username":"lzy-dev"},"change_message_id":"eb9aa24a3a6f55ab0ae48c19207c861a88f5200f","unresolved":false,"context_lines":[{"line_number":43,"context_line":"# Directory to use for lock files. Default to a temp directory"},{"line_number":44,"context_line":"# (string value). This setting needs to be the same for both"},{"line_number":45,"context_line":"# glance-scrubber and glance-api."},{"line_number":46,"context_line":"#lock_path\u003d\u003cNone\u003e"},{"line_number":47,"context_line":"lock_path\u003d/tmp"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"# \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d Security Options \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/plain","patch_set":5,"id":"AAAATH%2F%2Fzns%3D","line":46,"updated":"2013-10-09 15:28:24.000000000","message":"remove this useless line please.","commit_id":"711041b7e3ba5259df96a7078124796d9ae28a3c"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"ea9aafd509435366c9659e505b38615f989e886b","unresolved":false,"context_lines":[{"line_number":43,"context_line":"# Directory to use for lock files. Default to a temp directory"},{"line_number":44,"context_line":"# (string value). This setting needs to be the same for both"},{"line_number":45,"context_line":"# glance-scrubber and glance-api."},{"line_number":46,"context_line":"#lock_path\u003d\u003cNone\u003e"},{"line_number":47,"context_line":"lock_path\u003d/tmp"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"# \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d Security Options \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/plain","patch_set":5,"id":"AAAATH%2F%2FzgA%3D","line":46,"in_reply_to":"AAAATH%2F%2Fzns%3D","updated":"2013-10-09 15:39:54.000000000","message":"Done","commit_id":"711041b7e3ba5259df96a7078124796d9ae28a3c"}],"glance/api/middleware/cache.py":[{"author":{"_account_id":6549,"name":"Zhi Yan Liu","email":"lzy.dev@gmail.com","username":"lzy-dev"},"change_message_id":"eb9aa24a3a6f55ab0ae48c19207c861a88f5200f","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            return None"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        with self.cache.get_cache_lock(image_id):"},{"line_number":128,"context_line":"            if not self.cache.is_cached(image_id):"},{"line_number":129,"context_line":"                return None"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        LOG.debug(_(\"Cache hit for image \u0027%s\u0027\"), image_id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2Fzjc%3D","line":128,"updated":"2013-10-09 15:28:24.000000000","message":"do you think it will be better if we adding locking control code to \u0027ImageCache.is_cached()\u0027 but here? IMO it\u0027s more consistent if we keep all necessary simultaneity control code in ImageCache level, we added locking code to \u0027cache_tee_iter()\u0027 also.\n\nBtw, do you think other ImageCache methods also need self.cache.get_cache_lock() protection?","commit_id":"711041b7e3ba5259df96a7078124796d9ae28a3c"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"ea9aafd509435366c9659e505b38615f989e886b","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            return None"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"        with self.cache.get_cache_lock(image_id):"},{"line_number":128,"context_line":"            if not self.cache.is_cached(image_id):"},{"line_number":129,"context_line":"                return None"},{"line_number":130,"context_line":""},{"line_number":131,"context_line":"        LOG.debug(_(\"Cache hit for image \u0027%s\u0027\"), image_id)"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAATH%2F%2Fzdw%3D","line":128,"in_reply_to":"AAAATH%2F%2Fzjc%3D","updated":"2013-10-09 15:39:54.000000000","message":"Personally, when I see a method called is_cached(), I don\u0027t expect that to be doing any locking (especially locking calls which may block) on my behalf.\n\nI\u0027m open to discussion on this though, if people feel differently I\u0027m happy to move the locking into is_cached.\n\nI don\u0027t think other methods of ImageCache currently require use of get_cache_lock but I think having it in its own method makes the intent clear and consistent if it were to be used elsewhere.","commit_id":"711041b7e3ba5259df96a7078124796d9ae28a3c"}],"glance/image_cache/__init__.py":[{"author":{"_account_id":1390,"name":"Paul Bourke","email":"pauldbourke@proton.me","username":"pauldbourke"},"change_message_id":"fa46b4089f3603e4e4cbbcb46bda46006163a355","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        :param image_id: Image ID"},{"line_number":137,"context_line":"        \"\"\""},{"line_number":138,"context_line":"        return lockutils.lock(\u0027cache-%s\u0027 % image_id, lock_path\u003d\u0027/tmp\u0027,"},{"line_number":139,"context_line":"                              lock_file_prefix\u003d\u0027glance-\u0027, external\u003dTrue)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def delete_all_cached_images(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAASn%2F%2FA%2Bk%3D","line":138,"updated":"2013-09-13 14:24:49.000000000","message":"Hardcoding /tmp here is probably not ideal.  Have a look at the lock_path setting the scrubber uses in glance-api.conf - it may or may not make sense here.","commit_id":"434ebf5df9c088fb689440099a7f53a40aa1b95f"},{"author":{"_account_id":6484,"name":"Feilong Wang","email":"hustemb@gmail.com","username":"flwang"},"change_message_id":"427b47956e9853a4f0344e1cae5e1d89024b2384","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        :param image_id: Image ID"},{"line_number":137,"context_line":"        \"\"\""},{"line_number":138,"context_line":"        return lockutils.lock(\u0027cache-%s\u0027 % image_id, lock_path\u003d\u0027/tmp\u0027,"},{"line_number":139,"context_line":"                              lock_file_prefix\u003d\u0027glance-\u0027, external\u003dTrue)"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":"    def delete_all_cached_images(self):"}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAASn%2F%2FA54%3D","line":138,"in_reply_to":"AAAASn%2F%2FA%2Bk%3D","updated":"2013-09-13 14:46:57.000000000","message":"Good suggestion, Paul. But I think if we use the lock_path, maybe we have to miss a little bit flexibility since the cache lock path has to be shared with scrubber. But I think it\u0027s ok :)","commit_id":"434ebf5df9c088fb689440099a7f53a40aa1b95f"},{"author":{"_account_id":455,"name":"Stuart McLaren","email":"stuart.mclaren@hpe.com","username":"stuart-mclaren"},"change_message_id":"cb4e0300b154a38b8564e6eb5d1452de35f5b4d3","unresolved":false,"context_lines":[{"line_number":40,"context_line":"                      \u0027cache without being accessed\u0027)),"},{"line_number":41,"context_line":"    cfg.StrOpt(\u0027image_cache_dir\u0027,"},{"line_number":42,"context_line":"               help\u003d_(\u0027Base directory that the Image Cache uses.\u0027)),"},{"line_number":43,"context_line":"    cfg.StrOpt(\u0027cache_lock_path\u0027, default\u003d\u0027/tmp\u0027,"},{"line_number":44,"context_line":"               help\u003d_(\u0027Directory to store cache lock files.\u0027)),"},{"line_number":45,"context_line":"]"},{"line_number":46,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAS3%2F%2Fu2k%3D","line":43,"updated":"2013-09-20 12:25:02.000000000","message":"Possibly being a little overly paranoid, any user can write to /tmp, so could fill it to 100%, which would mean some kind of breakage. How hard would it be to default to something else?","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"de2ac5fee2ceaef8aed9a6b42d04e0d3dbca2c89","unresolved":false,"context_lines":[{"line_number":40,"context_line":"                      \u0027cache without being accessed\u0027)),"},{"line_number":41,"context_line":"    cfg.StrOpt(\u0027image_cache_dir\u0027,"},{"line_number":42,"context_line":"               help\u003d_(\u0027Base directory that the Image Cache uses.\u0027)),"},{"line_number":43,"context_line":"    cfg.StrOpt(\u0027cache_lock_path\u0027, default\u003d\u0027/tmp\u0027,"},{"line_number":44,"context_line":"               help\u003d_(\u0027Directory to store cache lock files.\u0027)),"},{"line_number":45,"context_line":"]"},{"line_number":46,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAS3%2F%2Fu2E%3D","line":43,"in_reply_to":"AAAAS3%2F%2Fu2k%3D","updated":"2013-09-20 12:37:59.000000000","message":"It would not be hard at all, can you suggest an alternative?","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"},{"author":{"_account_id":455,"name":"Stuart McLaren","email":"stuart.mclaren@hpe.com","username":"stuart-mclaren"},"change_message_id":"cb4e0300b154a38b8564e6eb5d1452de35f5b4d3","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        \"\"\""},{"line_number":132,"context_line":"        return self.driver.get_cached_images()"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def get_cache_lock(self, image_id):"},{"line_number":135,"context_line":"        \"\"\""},{"line_number":136,"context_line":"        Returns a lock for the image"},{"line_number":137,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAS3%2F%2Fu2c%3D","line":134,"updated":"2013-09-20 12:25:02.000000000","message":"We could potentially provide this as a decorator, and decorate functions that require the lock (cache_tee_iter, is_cached). Not sure if that\u0027s a big win or not.","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"},{"author":{"_account_id":455,"name":"Stuart McLaren","email":"stuart.mclaren@hpe.com","username":"stuart-mclaren"},"change_message_id":"87f6d6eed481d0ee216863a4e3f215d06fd45dbf","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        \"\"\""},{"line_number":132,"context_line":"        return self.driver.get_cached_images()"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def get_cache_lock(self, image_id):"},{"line_number":135,"context_line":"        \"\"\""},{"line_number":136,"context_line":"        Returns a lock for the image"},{"line_number":137,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAS3%2F%2FuLw%3D","line":134,"in_reply_to":"AAAAS3%2F%2Fu1I%3D","updated":"2013-09-20 15:38:47.000000000","message":"No, don\u0027t think you missed anything -- all sounds fair.","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"de2ac5fee2ceaef8aed9a6b42d04e0d3dbca2c89","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        \"\"\""},{"line_number":132,"context_line":"        return self.driver.get_cached_images()"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def get_cache_lock(self, image_id):"},{"line_number":135,"context_line":"        \"\"\""},{"line_number":136,"context_line":"        Returns a lock for the image"},{"line_number":137,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAS3%2F%2Fu1I%3D","line":134,"in_reply_to":"AAAAS3%2F%2Fu2c%3D","updated":"2013-09-20 12:37:59.000000000","message":"I\u0027m a little uncomfortable with including the lock in is_cached, it\u0027s possible that we might want to call that while someone else has the lock.\n\nI\u0027m doubly uncomfortable with wrapping cache_tee_iter as this would retain the lock even if caching failed (see lines 275-278).\n\nI don\u0027t think there\u0027s a great deal of win to be achieved by making this a wrapper. I\u0027m open to discussion on this though, maybe I\u0027ve missed something.","commit_id":"91e8543475e0ab4691b566a9cd3a00c6b459d72b"},{"author":{"_account_id":616,"name":"Mark Washenberger","email":"mark.washenberger@markwash.net","username":"markwash"},"change_message_id":"f0581b6fee42364e00d74d0f59039647a0ab8ffe","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        try:"},{"line_number":252,"context_line":"            current_checksum \u003d hashlib.md5()"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"            with self.get_cache_lock(image_id):"},{"line_number":255,"context_line":"                with self.driver.open_for_write(image_id) as cache_file:"},{"line_number":256,"context_line":"                    for chunk in image_iter:"},{"line_number":257,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAUH%2F%2Fl%2F8%3D","line":254,"updated":"2014-01-10 17:22:28.000000000","message":"Imagine two green threads are trying to cache the same image at the same time. The first one is going to arrive and hold on to this lock for the duration of the image transfer. The second one is going to arrive and wait (!) for the first to complete its transfer, and then its going to go ahead and attempt to cache the image again anyway. (maybe trying to cache again will fail because the driver doesn\u0027t allow it.)\n\nHowever, it seems unacceptable to me that the second process waits for a long time in order to try to cache, when we know it probably won\u0027t be necessary for it to cache it anyway.\n\nI think we should probably change this \"get_lock\" to a non-blocking operation. If the lock cannot be obtained, go ahead and iterate through the stream without bothering to try to cache.","commit_id":"ea103a76aceae9e85366af9e3c830aedf5b25acb"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"be3b92a64d50c50274a0ba4fe812809672e77750","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        try:"},{"line_number":252,"context_line":"            current_checksum \u003d hashlib.md5()"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"            with self.get_cache_lock(image_id):"},{"line_number":255,"context_line":"                with self.driver.open_for_write(image_id) as cache_file:"},{"line_number":256,"context_line":"                    for chunk in image_iter:"},{"line_number":257,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAUH%2F%2FYVA%3D","line":254,"in_reply_to":"AAAAUH%2F%2FcxI%3D","updated":"2014-01-20 14:46:12.000000000","message":"We do and I totally agree that having such a large delay is unacceptable. I\u0027m going to have a think about a better way to approach this.","commit_id":"ea103a76aceae9e85366af9e3c830aedf5b25acb"},{"author":{"_account_id":616,"name":"Mark Washenberger","email":"mark.washenberger@markwash.net","username":"markwash"},"change_message_id":"036c0f68150d4b50b0f5900b528deb127393de57","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        try:"},{"line_number":252,"context_line":"            current_checksum \u003d hashlib.md5()"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"            with self.get_cache_lock(image_id):"},{"line_number":255,"context_line":"                with self.driver.open_for_write(image_id) as cache_file:"},{"line_number":256,"context_line":"                    for chunk in image_iter:"},{"line_number":257,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAUH%2F%2FcxI%3D","line":254,"in_reply_to":"AAAAUH%2F%2Ffhg%3D","updated":"2014-01-13 19:07:05.000000000","message":"I think right now we currently allow multiple transfers of the same image coming from the backend, don\u0027t we? While it would be nice if we could limit multiple transfers, we can\u0027t afford to do so at the cost of a large delay in starting the download.","commit_id":"ea103a76aceae9e85366af9e3c830aedf5b25acb"},{"author":{"_account_id":455,"name":"Stuart McLaren","email":"stuart.mclaren@hpe.com","username":"stuart-mclaren"},"change_message_id":"009cf5b5375d7cfe0a327c578fcb619db0d927a7","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        try:"},{"line_number":252,"context_line":"            current_checksum \u003d hashlib.md5()"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"            with self.get_cache_lock(image_id):"},{"line_number":255,"context_line":"                with self.driver.open_for_write(image_id) as cache_file:"},{"line_number":256,"context_line":"                    for chunk in image_iter:"},{"line_number":257,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAUH%2F%2B68o%3D","line":254,"in_reply_to":"AAAAUH%2F%2Fl%2F8%3D","updated":"2014-01-20 18:28:56.000000000","message":"Hi Mark,\n\nMany thanks for your comment. (I was a little surprised that no one had specifically commented on this aspect of the behaviour change!).\n\n\u003e I think we should probably change this \"get_lock\" to a non-blocking operation. If the \u003e lock cannot be obtained, go ahead and iterate through the stream without bothering \u003e to try to cache.\n\nThe main driver of this change for us is that our backend can get over-loaded with very (and I mean very!) large numbers of requests for the same image data. Limiting to one backend request (per node) for a specific image provides some basic throttling. We have several glance API servers load balanced (round-robbined), so its only for \u0027large\u0027 number of GETs of the same image that the throttle will actually kick in.\n\nPerhaps an (off by default?) config option such as \u0027throttle_swift_object_requests\u003dFalse\u0027 would allow stability for large installations while leaving smaller installations unchanged?\n\nProbably the best option here would be to allow threads/processes to start to consume cached data before the image has been fully cached. I\u0027m just afraid that we wouldn\u0027t have the cycles for that right now...","commit_id":"ea103a76aceae9e85366af9e3c830aedf5b25acb"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"05704a1c49a3e0494d14b713855f6757417c871b","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        try:"},{"line_number":252,"context_line":"            current_checksum \u003d hashlib.md5()"},{"line_number":253,"context_line":""},{"line_number":254,"context_line":"            with self.get_cache_lock(image_id):"},{"line_number":255,"context_line":"                with self.driver.open_for_write(image_id) as cache_file:"},{"line_number":256,"context_line":"                    for chunk in image_iter:"},{"line_number":257,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAAUH%2F%2Ffhg%3D","line":254,"in_reply_to":"AAAAUH%2F%2Fl%2F8%3D","updated":"2014-01-13 11:07:12.000000000","message":"Hmm. My concern with that approach is that it\u0027s possible to still have multiple transfers of the same image coming from the back-end.\n\nMy understanding is that, currently, the second thread would block on the get_cache_lock call in process_request in glance/api/middleware/cache.py, then once the lock is released, return the image from cache. i.e. 1 transfer from the backend to satisfy both requests. It\u0027s entirely possible that I\u0027m wrong about that though, feel free to tell me otherwise.\n\nI understand the concern with having the second thread block until the full image is in the cache, though...\n\nThis needs more thought (and coffee).","commit_id":"ea103a76aceae9e85366af9e3c830aedf5b25acb"}],"glance/tests/unit/test_cache_middleware.py":[{"author":{"_account_id":6484,"name":"Feilong Wang","email":"hustemb@gmail.com","username":"flwang"},"change_message_id":"427b47956e9853a4f0344e1cae5e1d89024b2384","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            def get_caching_iter(self, image_id, image_checksum, app_iter):"},{"line_number":138,"context_line":"                pass"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"            @contextmanager"},{"line_number":141,"context_line":"            def get_cache_lock(self, image_id):"},{"line_number":142,"context_line":"                yield"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAASn%2F%2FA5o%3D","line":140,"updated":"2013-09-13 14:46:57.000000000","message":"Is it possible to add a test case for the locker?","commit_id":"434ebf5df9c088fb689440099a7f53a40aa1b95f"},{"author":{"_account_id":7817,"name":"Thomas Leaman","email":"thomas.leaman@hp.com","username":"bugsduggan"},"change_message_id":"854e4a4033e27c8d4a847f6dac2aa001021b00b0","unresolved":false,"context_lines":[{"line_number":137,"context_line":"            def get_caching_iter(self, image_id, image_checksum, app_iter):"},{"line_number":138,"context_line":"                pass"},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"            @contextmanager"},{"line_number":141,"context_line":"            def get_cache_lock(self, image_id):"},{"line_number":142,"context_line":"                yield"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"AAAAS3%2F%2F%2BKA%3D","line":140,"in_reply_to":"AAAASn%2F%2FA5o%3D","updated":"2013-09-16 11:31:14.000000000","message":"I think since this method is only wrapping a function call to oslo lockutils (which is unit tested in that project), it\u0027s unnecessary to test it here also.","commit_id":"434ebf5df9c088fb689440099a7f53a40aa1b95f"}]}
