New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPARK-16986][WEB-UI] Converter Started, Completed and Last Updated to client time zone in history page #19640
Conversation
@wangyum this was a WontFix. See linked JIRAs for some of the discussion and implications. |
This is a significant behavior change though. If anything we need to move towards GMT, not towards varying with whatever the server's timezone is. |
Test build #83326 has finished for PR 19640 at commit
|
Test build #83383 has finished for PR 19640 at commit
|
retest this please |
Test build #83385 has finished for PR 19640 at commit
|
@srowen We can configure time zone by |
@@ -426,6 +426,10 @@ class SparkHadoopUtil extends Logging { | |||
ugi.getAuthenticationMethod() == UserGroupInformation.AuthenticationMethod.PROXY | |||
} | |||
|
|||
def getTimeZone: TimeZone = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would write it like
def timeZone: TimeZone = TimeZone.getTimeZone(sparkConf.get("spark.history.timeZone", "GMT"))
@@ -426,6 +426,10 @@ class SparkHadoopUtil extends Logging { | |||
ugi.getAuthenticationMethod() == UserGroupInformation.AuthenticationMethod.PROXY | |||
} | |||
|
|||
def getTimeZone: TimeZone = { | |||
TimeZone.getTimeZone(sparkConf.get("spark.history.timeZone", "GMT")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit confusing using spark.history.timeZone
property in getTimeZone method of SparkHadoopUtil.
cc @ueshin |
@@ -2742,6 +2742,11 @@ private[spark] object Utils extends Logging { | |||
} | |||
} | |||
|
|||
def getTimeZone: TimeZone = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please image that this method will be used outside scope of the current issue?
What's about users who does not have spark history at all?
The name of method, the class and the package does not tell us that this method somehow related ONLY to history server, such API makes me easy to do wrong assumptions.
Test build #83480 has finished for PR 19640 at commit
|
@@ -2742,6 +2742,11 @@ private[spark] object Utils extends Logging { | |||
} | |||
} | |||
|
|||
def getTimeZone: TimeZone = { | |||
val sparkConf = new SparkConf(false).loadFromSystemProperties(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make SparkConf as a input param instead of create a new instance for every function call?
Test build #83550 has finished for PR 19640 at commit
|
@@ -426,6 +426,8 @@ class SparkHadoopUtil extends Logging { | |||
ugi.getAuthenticationMethod() == UserGroupInformation.AuthenticationMethod.PROXY | |||
} | |||
|
|||
def getHistoryServerTimeZone: String = sparkConf.get("spark.history.timeZone", "GMT") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add this config to internal/config
.
I'm not a fan of this change; this seems like it should be done client-side, so that the browser shows timestamps in its own time zone, and the server should only know about UTC. The API probably should be left alone - especially because with this change it becomes a little confusing, since you have a timestamp in whatever is the configured server tz, and the raw value which is in UTC. |
Test build #83601 has finished for PR 19640 at commit
|
Since a spark cluster may be used by people from different timezones, I think at server side we should just store seconds from unix epoch(time epoch), which is comparable though different timezones. For the REST API, personally I think the server just need to send time epoch, but for ease of use, sending a timestamp string with GMT is acceptable. For the UI part, I think it's more reasonable to interpret the time epoch using browser's local timezone, but we don't need a config. |
@cloud-fan For the UI part, how about this PR: #14577 |
I think it makes sense, but the implementation is too hacky. We should extract the time epoch and convert it to timestamp string with local timezone. |
Test build #83727 has finished for PR 19640 at commit
|
if (date <= 0) return "-"; | ||
else return date.split(".")[0].replace("T", " "); | ||
if (date <= 0) { | ||
return "-"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just for curious, what does a single -
mean here? invalid value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, invalid value. Maybe we can remove this.
how about BTW the |
It is client local time zone: But the format is |
maybe we can move |
why it has |
sorry, I mean we should follow the format we use in completed, started... |
@@ -352,7 +352,7 @@ class HistoryServerSuite extends SparkFunSuite with BeforeAndAfter with Matchers | |||
.map(_.get) | |||
.filter(_.startsWith(url)).toList | |||
|
|||
// there are atleast some URL links that were generated via javascript, | |||
// there are at least some URL links that were generated via javascript, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix a typo
@@ -46,3 +46,25 @@ function formatBytes(bytes, type) { | |||
var i = Math.floor(Math.log(bytes) / Math.log(k)); | |||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; | |||
} | |||
|
|||
function padZeroes(num) { | |||
return ("0" + num).slice(-2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
num.toString().padStart(2, "0")
cause org.apache.spark.deploy.history.HistoryServerSuite test failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you know why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
padStart
with poor compatibility:
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 57 | 15 | 48 | No | 44 | 10 |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does the test use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TagNameQuery("a") gets result from WebBrowser, This browser doesn't support this function.
@@ -37,11 +37,6 @@ function makeIdNumeric(id) { | |||
return resl; | |||
} | |||
|
|||
function formatDate(date) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to utils.js
} | ||
|
||
function getTimeZone() { | ||
return new Date().toString().match(/\(([A-Za-z\s].*)\)/)[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about Intl.DateTimeFormat().resolvedOptions().timeZone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This timeZone seems incorrect. Safari gets Asia/Shanghai
, but Chrome gets America/Chicago
on the same computer.
How about just include this change to release notes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you have proxy on your chrome? It works fine at my Chrome.
@@ -56,6 +56,10 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("") | |||
} | |||
|
|||
{ | |||
<p>Client local time zone: <span id="time-zone"></span></p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any more feedback on the naming?
Test build #83848 has finished for PR 19640 at commit
|
retest this please. |
Test build #83868 has finished for PR 19640 at commit
|
try { | ||
return Intl.DateTimeFormat().resolvedOptions().timeZone; | ||
} catch(ex) { | ||
return new Date().toString().match(/\((.*)\)/)[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you really want to keep this code, please add comment to explain this regex.
} | ||
|
||
function getTimeZone() { | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some old browser doesn't support this function. so I surround with try catch.
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | 24 | 12 | 29 | 11 | 15 | 10 |
computed timeZone | 35 | 14 | 53 | No | 30 | 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @srowen does Spark have a guarantee about which version of which browser to support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spark does not have a list of supported browsers, from my experience most of us just test new UI changes on whatever browsers we have (In my case the latest Safari, Chrome and Firefox ESR). Though I'd like to think we don't have any IE users, we can't make that assumption while IE 11 is still supported by MS.
Test build #83900 has finished for PR 19640 at commit
|
Test build #83902 has finished for PR 19640 at commit
|
I'm still not 100% convinced this is the best change, but the implementation LGTM. |
It's a pure UI change so no compatibility issues. The new UI LGTM |
JS is not really my thing, but other have reviewed and seem ok. I'm fine with this being done client-side. Merging to master. |
What changes were proposed in this pull request?
This PR is converted the
Started
,Completed
andLast Updated
to client local time in the history page.How was this patch tested?
Manual tests for Chrome, Firefox and Safari
Before modifying:
After modifying: