{ "id": "131668", "key": "TIMOB-17327", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "16704", "description": "Release 3.5.0", "name": "Release 3.5.0", "archived": false, "released": true, "releaseDate": "2015-01-13" }, { "id": "16593", "description": "Release 4.0.0", "name": "Release 4.0.0", "archived": false, "released": true, "releaseDate": "2015-05-21" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2014-12-05T19:01:17.000+0000", "created": "2014-06-13T00:35:47.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [], "versions": [ { "id": "15971", "description": "Release 3.2.3", "name": "Release 3.2.3", "archived": false, "released": true, "releaseDate": "2014-04-30" } ], "issuelinks": [ { "id": "43726", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "138312", "key": "MOD-1774", "fields": { "summary": "appcelerator.syncserver.client issue with progress callback", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2014-12-11T19:17:50.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "The docs for the HTTPClient ondatastream callback state:\r\n{quote}\r\nFunction to be called at regular intervals as the request data is being received.\r\n\r\nMust be set before calling open.\r\n\r\nThe progress property of the event will contain a value from 0.0-1.0 with the progress of the request.\r\n{quote}\r\n\r\nIn my app the progress number returned is not always between zero and one.\r\n\r\nSome example values I have received are:\r\n * 0.4423390328884125\r\n * 0.9344342350959778\r\n * 1\r\n * 1.599303126335144\r\n * 1.453825831413269\r\n * 1.2088645696640015\r\n * 1.066718339920044\r\n * 2.387096881866455\r\n * 345 (this one is pretty wild)\r\n\r\nSo some are in the range, some are not, and that one 345 is crazy.\r\n\r\nI'm not sure if it matters but I am running a lot of requests at once (could they possibly interfere with each other?).\r\nA few of them are requests to a website that return a bunch of JSON data.\r\nThe rest are requests for image files from the same web server.\r\nThere are about 40 - 50 requests total.\r\nThe requests are using a username and password to get through http authentication.\r\n\r\nIf I run the same set of requests multiple times (within one run of the app) in a row they return exactly the same progress numbers each time.\r\nIf I stop and start the app again I get different progress numbers.\r\nAlthough the 345 number is always there.\r\nThe 345 number is for a request for around 100kb of JSON.\r\n\r\nThe numbers mid way between 1 & 2 (and 345) are the JSON requests (although some of these requests return 1).\r\nThe numbers in the 2s seem to all be image requests where the request has failed.\r\nAll other images seem to give correct (or almost correct results), being between 0 and about 1.01.\r\n\r\nSo it would seem that the JSON requests and the erroring requests are the ones that return incorrect progress.\r\nAnd maybe the docs should mention rounding when they say 1.0, because a see a lot between 1.0 and 1.01.\r\n\r\nI can provide more information if required.\r\nI will see if I can get a simple code example that exhibits this same problem.", "attachment": [], "flagged": false, "summary": "HTTPClient ondatastream returns progress outside of 0.0 - 1.0", "creator": { "name": "rooby", "key": "rooby", "displayName": "Reuben Turk", "active": true, "timeZone": "Australia/Sydney" }, "subtasks": [], "reporter": { "name": "rooby", "key": "rooby", "displayName": "Reuben Turk", "active": true, "timeZone": "Australia/Sydney" }, "environment": "- Application type: mobile\r\n- Titanium SDK: CLI version 3.2.3, Titanium SDK version 3.2.3.GA\r\n- Platform & version: iOS 7.x\r\n- Device: iOS simulator (iPhone Retina (4 inch 64-bit)\r\n- Host Operating System: OSX 10.9\r\n- Titanium Studio: 3.2.3.201404181442", "comment": { "comments": [ { "id": "318070", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Can we confirm if this happens the same way for 3.3.0.GA?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-08-11T21:17:56.000+0000", "updated": "2014-08-11T21:17:56.000+0000" }, { "id": "332898", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "Android native accepts a starting value (0) and max value (e.g. 100) and returns an integer value between those ranges representing the amount completed. If developers stick to 0 and 100, that integer value corresponds to a percent complete.\r\n\r\nOur SDK on both Android and iOS returns a float value between 0 and 1. I've tested this using the KitchenSink app, SDK 3.4.1.GA, to confirm that the values match our documentation.\r\n\r\nBoth platforms natively perform a simple division to determine the percent complete, using the total bytes to send/receive and the bytes already sent/received. If our SDK or the client application sends an incorrect value for the total bytes, then the resulting progress value will likewise be off. For example, if the SDK/client app specifies that 100 KB as the total, yet the actual size is greater, once more than 100KB is sent, e.progress would report values greater than 1. ", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-11-19T14:07:35.000+0000", "updated": "2014-11-19T15:09:16.000+0000" }, { "id": "332900", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Would it be fair (for now) to just place a floor of 0 and a ceiling of 1? Even if the calculation is still off, at least it would be within the documented range and not cause ancillary effects?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-11-19T14:53:56.000+0000", "updated": "2014-11-19T14:53:56.000+0000" }, { "id": "332907", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "Ingo, I think that would be an okay short term fix. I think the problem stems from payloads of small or indeterminate sizes. A JSON payload might be small enough that basic block sizes being sent would be larger than the actual payload, leading to values like 345. Perhaps our SDK assumes a default payload size if none is specified / determinable? If that guesstimate is too small, it would also lead to overly-large progress values. \r\n\r\nWe should make sure to Math.abs() so we don't get negative values. ", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-11-19T15:12:52.000+0000", "updated": "2014-11-19T15:12:52.000+0000" }, { "id": "333010", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Android + iOS master PR: https://github.com/appcelerator/titanium_mobile/pull/6364\r\n\r\nPR adds ceiling for both ondatastream and onsendstream progress. Doesn't look like progress will ever be below 0, so a floor seem unnecessary.", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-11-20T04:39:43.000+0000", "updated": "2014-11-20T05:21:09.000+0000" }, { "id": "333118", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Hey Tim,\r\nThe crash you are seeing is not about this bug. Looks like you're passing \"null\" when a \"string\" was expected. According to the module's source code, your JS code looks somewhat like this\r\n{code}\r\nvar Crittercism = require(‘com.appcelertor.apm);\r\nCrittercism.init ( \"string is supposed to be here\" ); \r\n{code}\r\nbut you're not passing a string, instead you're passing \"null\" (according to the error message). Make sure that the string is valid and it is what you expect it to be.", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-11-20T19:16:57.000+0000", "updated": "2014-11-20T19:16:57.000+0000" }, { "id": "334672", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "We are now setting the progress to 1 if it is below 0. This is how it worked up until TiSDK 3.3.0.\r\nMaking this change to address MOD-1774\r\n\r\nPRs = Hieu's + progress floor of 0 (will now work like before APSHTTPClient aka pre 3.3.0)\r\nmaster: https://github.com/appcelerator/titanium_mobile/pull/6424\r\n3_5_X (I'm guessing you will want this fix here): https://github.com/appcelerator/titanium_mobile/pull/6425", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-12-03T22:33:47.000+0000", "updated": "2014-12-03T23:05:43.000+0000" }, { "id": "334693", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Vishal has an idea of a better way for us to handle the situation where we can't figure out the percentage.\r\n\r\nThe plan is for us to return -1 for any value that does not fall between 0-1 instead of sending a false 1.\r\nThis way the developer will be able to tell when they are not getting a real value because we can't calculate it. We will have a constant for -1 as well.\r\nThis will be done for both iOS and Android.\r\n\r\nIf you have any issue with this, please comment.\r\n[~ingo] [~skypanther] [~hpham]", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-12-03T23:37:49.000+0000", "updated": "2014-12-03T23:37:49.000+0000" }, { "id": "334706", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "My concern with returning -1 is that most apps I've seen use e.progress to either output a percentage complete or to use as input to our progress bar component. By returning -1, these apps will output -100% complete, which will cause confusion. I'm not sure how our progress bar component would handle receiving a -1 value when it expects a 0-1 range. Furthermore, developers might not have control over the server to fix an issue where it's reporting invalid sizes that are the underlying cause of this issue. \r\n\r\nWould it be better to return 0? There'd be no odd output or the progress bar would simply not move. I guess they wouldn't be made specifically aware that there's an issue with their server.\r\n\r\n", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-12-04T00:10:14.000+0000", "updated": "2014-12-04T00:10:14.000+0000" }, { "id": "334848", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~skypanther],\r\n\r\nThe plan is that you will be able to check the value before setting the progress indicator value as in the example below.\r\n\r\n{code}\r\nonsendstream: function(e) {\r\n if (e.progress == Ti.Network.PROGRESS_UNKNOWN) {\r\n // Do something special if you like\r\n } else {\r\n progressBar.value = e.progress;\r\n }\r\n}\r\n{code}\r\n\r\nIf you do not do this check for whatever reason, the progress bar will treat the -1 as a 0 on both iOS and Android. Test code below.\r\n\r\n{code}\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor : 'white',\r\n layout: 'vertical'\r\n});\r\nwin.open();\r\n\r\nvar pb=Titanium.UI.createProgressBar({\r\n top:30,\r\n width:250,\r\n height:'auto',\r\n min:0,\r\n max:1,\r\n value:0\r\n});\r\nwin.add(pb);\r\npb.show();\r\n\r\naddButton({\r\n title: '-1',\r\n callback: function(e) {\r\n pb.value = -1;\r\n }\r\n});\r\n\r\naddButton({\r\n title: '0',\r\n callback: function(e) {\r\n pb.value = 0;\r\n }\r\n});\r\n\r\naddButton({\r\n title: '0.5',\r\n callback: function(e) {\r\n pb.value = 0.5;\r\n }\r\n});\r\n\r\naddButton({\r\n title: '1',\r\n callback: function(e) {\r\n pb.value = 1;\r\n }\r\n});\r\n\r\nfunction addButton(params) {\r\n var button = Ti.UI.createButton({\r\n top: 40,\r\n title: params.title\r\n });\r\n button.addEventListener('click', function() {\r\n params.callback();\r\n });\r\n win.add(button);\r\n}\r\n{code}", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-12-04T16:29:07.000+0000", "updated": "2014-12-04T16:29:07.000+0000" }, { "id": "334849", "author": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "body": "Cool, returning -1 makes total sense then. Thanks for the clarification.", "updateAuthor": { "name": "skypanther", "key": "skypanther", "displayName": "Tim Poulsen", "active": true, "timeZone": "America/New_York" }, "created": "2014-12-04T16:32:02.000+0000", "updated": "2014-12-04T16:32:02.000+0000" }, { "id": "334885", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Updated PRs to return -1 for invalid progress\r\nmaster: https://github.com/appcelerator/titanium_mobile/pull/6424\r\n3_5_X: https://github.com/appcelerator/titanium_mobile/pull/6425", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-12-04T19:47:27.000+0000", "updated": "2014-12-04T19:47:27.000+0000" }, { "id": "336047", "author": { "name": "wluu", "key": "wluu", "displayName": "Wilson Luu", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as fixed. Verified that the fix converts any progress value outside the range of 0.0 - 1.0 to -1. And, also verified Ti.Network.PROGRESS_UNKNOWN returns -1.\r\n\r\nTested on:\r\n\r\nAppcelerator Studio, build: 3.4.1.201410281743\r\nSDK build: 3.5.0.v20141211093314\r\nCLI: 3.4.1\r\nAlloy: 1.5.1\r\nXcode: 6.2 beta \r\nDevices: iPad Air (8.1)", "updateAuthor": { "name": "wluu", "key": "wluu", "displayName": "Wilson Luu", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-12-11T19:16:58.000+0000", "updated": "2014-12-11T19:16:58.000+0000" } ], "maxResults": 26, "total": 26, "startAt": 0 } } }