About Wayne Wan

Travel & Sports & Work
Apr 16

How to save canvas as an image(Chrome, Firefox, IE)

 

Save canvas as an image in chome and firefox is easy, the code below will work.

....
function saveAsImage(ele){
    var c=document.getElementById("myCanvas");
    var image = c.toDataURL().replace("image/png", "image/octet-stream");
    ele.download = 'image.png';
    ele.href = image;
}
....
<body>
    ...
    <a href="javascript:void(0)" onclick="saveAsImage(ele)">downloadCanvas</a>
    ...
<body>

But, in IE(obsolutely in IE>=9), the code does not work, after some investigation in MSDN, I found a work around:

function saveAsPng(ele){
    window.BlobBuilder = window.BlobBuilder || window.MSBlobBuilder || 
           window.WebKitBlobBuilder || window.MozBlobBuilder;
    var toBlob = c.toBlob || c.msToBlob;
    var saveBlob = window.navigator.saveBlob || window.navigator.msSaveBlob;
    if(window.BlobBuilder && toBlob && saveBlob){
        var blobBuilder = new window.BlobBuilder();
        blobBuilder.append(toBlob.bind(c)());
        saveBlob.bind(window.navigator)(blobBuilder.getBlob(), "image.png");
    }else{
        var image = c.toDataURL().replace("image/png", "image/octet-stream");
        ele.download = 'image.png';
        ele.href = image;
    }
}

The “BlobBuilder”, “toBlob” and “saveBlob” methods can use in MS browser, so we use these methods to recognize MS browser.

Sep 22

cms垃圾回收的生命周期

转自:https://blogs.oracle.com/jonthecollector/entry/hey_joe_phases_of_cms

CMS (-XX:+UseConcMarkSweepGC) or the concurrent mark sweep GC could have been called the mostly concurrent mark sweep GC and here’s why.

These are the phases of a CMS concurrent collection.

1. Initial mark. This is the the start of CMS collection. This is a stop-the-world phase. All the applications threads are stopped and CMS scans the application threads (e.g. the thread stacks) for object references.

2. Concurrent mark. This is a concurrent phase. CMS restarts all the applications threads and then starting from the objects found in 1), it finds all the other live objects. Almost (see the remark phase).

3. Precleaning phase. This is a concurrent phase. This phase is an optimization and you don’t really need to understand what it does so feel free to skip to 4. While CMS is doing concurrent marking (2.), the application threads are running and they can be changing the objects they are using. CMS needs to find any of these changes and ultimately does that during the remark phase. However, CMS would like to discovery this concurrently and so has the precleaning phase. CMS has a way of recording when an application thread makes a change to the objects that it is using. Precleaning looks at the records of these changes and marks live objects as live. For example if thread AA has a reference to an object XX and passes that reference to thread BB, then CMS needs to understand that BB is keeping XX alive now even if AA no longer is.

4. The remark phase. The remark phase is a stop-the-world. CMS cannot correctly determine which objects are alive (mark them live), if the application is running concurrently and keeps changing what is live. So CMS stops all the application threads during the remark phase so that it can catch up with the changes the application has been making.

5. The sweep phase. This is a concurrent phase. CMS looks at all the objects and adds newly dead objects to its freelists. CMS does freelist allocation and it is during the sweep phase that those freelists get repopulated.

6. The reset phase. This is a concurrent phase. CMS is cleaning up its state so that it is ready for the next collection.

Mar 17

Tomcat源码分析(序)

 

转眼工作已经快10年了,娃也2岁了,最近大半年在试着转型,从纯开发向管理方向转,不是很顺,且这半年多代码写的比较少了,找不到前面两三年年的那种亢奋的感觉了,经常能为了搞掂一个点,一泡尿能憋一上午。所以私下里总想着找个流行的开源框架来读读,尝试过去读flume的代码,读的让人觉得恶心,flume的PMC chairman是个阿三,不是怎么喜欢阿三,读了几天,事情一多就没有坚持下去了,主要还是后来用的少了,也没什么动力去读了。还是回归质朴,读读tomcat这种不是那么花哨的东西,速度不用很快,坚持读下去,相信应该是有用的。而且据说tomcat 7 以后的代码重构的已经比较清爽了,不像之前那么杂乱无章的,让人摸不着头脑,看起来应该会读的比较舒服吧。

Feb 23

Observer pattern implementation in web application using Comet

     Observer pattern can be implemented easily in C/S based applications, but in web application area it is not easy to implement caused by the shortcoming of HTTP protocol. Currently we have some solutions : 

  1. browser plugins: we can use socket communication in flash or applet etc. by this we can implement C/S likely applications, the server side can push messages to the small application in browser side,  when the small application receives messages, it can communication with javascript engine. 
  2. comet : it also can be called "server push". it was based on long time polling, we start a request from browser side, the server side application keep the request live, by this we can keep sending messages to browser side. nowadays, some web application servers start to support comet, like : tomcat6/tomcat7 , jetty etc.. In tomcat, NIO is used to optimized the IO performance and decrease the expense of CPU. 
  3. HTML5 web socket. 

    Thinking of implementing the Observer pattern:

  1. send a request with the concerning message types, when server side received these messages, save these concerning message types in the session scope. Of course we can persistence these concerning message type in database, then we can design a customer independent notification user experience.  
  2. open a long time polling from the browser side, when server side received this request, we save the request related  response in a message send thread, at the same time we must keep this request live. Then we can send message signal to the message send thread. In the message send thread we can determine which message must write to which response.
Feb 22

MySQL replication configuration for Community Edition

    This is just a brief summary for the whole steps, more details please refer to : http://dev.mysql.com/doc/refman/5.5/en/replication.html

Steps: 

1. master and slave server must have the same database structure and same data;(dump data from master to slave).

2. for master server:set server-id=1 and open binary log(log-bin=mysql-bin.log)

    for slave server : set server-id=2.

3. start master server, use "show master status\G" to show binary log file name and position;

4. start slave server, use below command to set slave server's related master server info.

mysql> CHANGE MASTER TO

         ->     MASTER_HOST='master_host_name',

         ->     MASTER_USER='replication_user_name',

         ->     MASTER_PASSWORD='replication_password',

         ->     MASTER_LOG_FILE='recorded_log_file_name',

         ->     MASTER_LOG_POS=recorded_log_position;

5. check the log of master and slave server, if no errors, then means all ready, then execute start slave in slave server.
Reference command :  "show processlist\G" , "show master status\G", "show slave status\G" , "start slave" , "stop slave" , "reset slave" , "show variables like
*** "

Feb 14

BCDEdit Command-Line Options

 

Boot Configuration Data (BCD) files provide a store that is used to describe boot applications and boot application settings. The objects and elements in the store effectively replace Boot.ini.

BCDEdit is a command-line tool for managing BCD stores. It can be used for a variety of purposes, including creating new stores, modifying existing stores, adding boot menu options, and so on. BCDEdit serves essentially the same purpose as Bootcfg.exe on earlier versions of Windows, but with two major improvements:

  • BCDEdit exposes a wider range of boot options than Bootcfg.exe.
  • BCDEdit has improved scripting support. Continue reading
Jan 06

Forward-Backward function in Chrome

    Nowadays we are familiar with the forward and backward function of browser, but may be little of us know the real algorithm of it. In a recent project, I have to simulate a forward-backward function for our ajax based web application. So I spend some time on the forward-backward algorithm of Chrome. Continue reading

Dec 06

Nested method invoke in the same instance issue of Spring AOP

    Today, Spring AOP is widely used in transaction manage, but I found something that I had never noticed yet.
    The situation was :  I have a service class named KeywordExtendService , there are 2 methods in it named: "start" and "service". the service method will invoke the start method. but I config the pointcut like : execution(* com.waynewan.KeywordExtendService .start(..)) .  and the transaction propagation level is "REQUIRED",  so this means if there is an transaction it will use the exist one, if not it will create one. but the result is not as I guessed. when the start method invoked in the service method(no transaction configuration), there is no transaction start.  Continue reading