Friday, July 23, 2010

SessionStore in Rails

Recently, I am learning how to use Rails( the version is 2.3.5,ruby version is 1.8.6). I need to use session  in Rails。Considering about the scalability, we should store the session to database(MySQL 5.x). The default value of session_store in Rails is File, so we need to modify the configuration of environment.rb file which is located in config foler. The setting is:

config.action_controller.session_store = :active_record_store

But, unexpected progress is in the matter, when I modified the setting value, the website can not be open(Firefox), the error page is as below:imageI know it must be session issue. After checking the session table in database and the configuration of session in rails, no problem was found. But when I checked the log, I found the following error information:

Status: 500 Internal Server Error
  Mysql::Error: Data too long for column 'session_id' at row 1: INSERT INTO `sessions` (`updated_at`, `session_id`, `data`, `created_at`) VALUES('2010-07-23 01:17:05', 'BAh7CDoPc2Vzc2lvbl9pZCIlMDNlNTg0ZDg2NjJkZmFjZTdiMjUwN2ExNmYyNGNjNjAiCmZsYXNoSUM6J0FjdG
lvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhhc2h7AAY6CkB1c2VkewA6EF9jc3JmX3Rva2VuIjFWNStxMUc
4bThmUmJHQ3VHRGQ3Q2RJR2p1aStUejdtRmRtc0xJY1RIOUNrPQ==--6f29ea421cd0f14d5e8de70935515c26021c254f', 'BAh7AA==\n', '2010-07-23 01:17:05')

Obviously, the crux of problem is clearly that the session_id is too long instead of configuration of session. So I checked the columns of sessions table. Its definition is:

image However, I had setted the value of secret of session, like this:

config.action_controller.session = {
  :key => '_session',
  :secret      => 'f914e9b1bbdb829688de8512f5fea7d8e83fb35bfe2b56bcf1e6438d1d1b7837c532f8c2ece2a2
d0e37812e9b210824089b1810a4e238a61dfd922dc9dd62521'
}

Despite I changed it into shorter value, the error is still.

Finnally, I found the answer.It is incredible but simple. That is clearing cookie in the explorer. That's OK! Now, let's query the session table:

image

The length of session_id becomes normal and the system becomes normal too. It is really a trap that is tend to be ingored. Mark it!

Friday, July 16, 2010

Installing RadRails Plug-in in the MyEclipse

Preparation: Before installing it, I suggest you'd better install ruby, rails and MySQL at first. The installer package for ruby that I choose is rubyinstaller for windows version, you can download it from http://rubyinstaller.org. The process of installing is very simple, you only need to follow the wizard and do it(Notice: During installing, you must make sure the checkbox of Enable RubyGems option is checked. It's the default value):

image

After installing completed, you can open the command window and input the command line: Ruby –v. If the version of ruby can be displayed normally, it proved the installing was sucessful!(The installer would add the system path for ruby automatically. And my version of ruby is 1.8.6.)

Next, we should update Gem system. You can execute the command on the command windows: gem update –system; then we should execute the command "gem install -v=2.3.5 rails" to install Rails. After installed, you can execute the command "rails –v" to check the version of Rails.

Now, you need to install MySQL. Please pay attention to the version number of MySQL. It seams like the MySQL adapter that ruby provided is just for 5.0 version. The version of MySQL DB that I installed is 5.0.18 for windows. You can download it from MySQL official website. Here I omitted the process of installing for MySQL. If you want to verify whether the installing is sucessful, you might input the command line as below (Suppose the username and password all are "root"):

02

Then we need to install the gem for mysql. The gem I choosed is mysql-2.8.1-x86-mswin32.gem. After you fetch this file and save it in the installing directory for ruby(Suppose it is c:\ruby), you can switch the current directory to c:\ruby, and execute command line:

gem install mysql-2.8.1-x86-mswin32.gem

03 The system will give the result it showed "Sucessfully installed". But I don't know the specfic reason that the gem installer cann't install the related document and give the error message "No definition for …".

Now, we are going to install the RadRails plug-in, it is my topic of this article. The version of MyEclipse is 8.5. The installing steps are as below:

1. Start MyEclipse application, and choose "MyEclipse" menu, go to "MyEclipse Configuration Center" item.

04

2. Choose "Software" tag, and click the "add site" on the left side:

05 It will pop up the dialog box:

06

3. Input the name of site(The naming is up to you, I choose the name "Rails") and URL:

http://download.aptana.com/tools/radrails/plugin/install/radrails-bundle

4. Now, the section which name is "Personal Site" emerges from the left side. There is the name of new site "Rails":

07 5. Click the site name, the system will connect to the URL and download the remoted data. It will last about one minute, then it will show the treeview structure of Rails-Aptana RadRails. Now you can click it, there should be show the message "Managed Changes:1 Change" in the Pending Changes section which locates in the bottom and right of the screen. 

08

6. Click "Apply 1 Change" button, the system will validate the MyEclipse at first:

 0910 Then, It will pop up the dialog box "Accept Software License". We might select it and click "Next" button:

11Then, click "Update" button, it is executing update operation:

12 

The process will progress slowly. It is very strange that it is normal at the beginning of update operation, but the error occurs frequently at the end of operation:

13 Don't worry! Please wait for a few minutes, it will pop up the dialog box to show the error information:

14 At this time, you must click "Back" button to back the dialog box, and click "update" button again, it will restart to update. It will skip the sucessful operation and repeat the wrong operation. Unfortunally, only one wrong operation can be corrected every time, the error diaglog box is popped up as ghost. I don't know how to handle this issue, the one way that I know is to repeat the process until it corrected all wrong operation. I try to find out the reason, but I failed. The error is not related to bandwidth of network.

This terrible process will be lasted for about two hours andsuccessful final. The system requires to restart MyEclipse.

After installing the plug-in, the system maybe notices the user to auto-install gems, the diagram is as below:

15 Although I didn't try these, but I strongly suggest not to install these gems because these gems with the latest version will be conflicted with the existed version.

To validate whether the plug-in had been installed sucessfully, and integrated with ruby, rails and MySQL, we might create the sample project to check it. At first, we will change the view in MyEclipse into RadRails:

16 Then, you can create a new rails project on the ruby explorer:

17 Input the project name "Sample" in the pop-up dialog box, and select mysql database:

18Click the "Finish" button, it will execute the rails command automaticlly and generate the related folders and files with Rails. The directory structure is as below:

19  Now, please open the database.yaml file in the directory with "config", and modify the configuration like this(The precondition is that I had create the database "oa" in the MySQL):

20 Then switch to the server window in MyEclipse, and start the server of Sample project(using WebRick server) with the default port number 3000. After server is running, you can open the explorer such as Internet Explorer or Firefox, and input the URL:http://localhost:3000:

21 Click the link "About your application's environment", if the information related to ruby can be display correctly, it proved the plug-in had been installed sucessfully and the development environment was prepared normally.

Tuesday, July 13, 2010

Art of Object Design on MPDay

Last sunday, I gave a speaking as a speaker in the msup open day conference in ShangHai. My topic was Art of Object Design, mainly focused on low level design in the software development lifecycle. I want to dig the essence of software design deeply. As we know, there are amount of principles and patterns for software achitecting and design. It is impossible to grasp all of these. You know more, understand less. Through by analyzing the essence and core idea of design patterns and architecture patterns, I summarized seven principles including Reusability, Extensibility, Separation, Change, Simplicity, Consistency, Indirection.

   

Reusability

The most evil enemy in the software development is repeat. It results in developing repeaded so that we cann't reuse some components and functions effeciency. It would generate the bad smell of solution sprawl. How to avoid repeat? We must keep the objects to be fine-grained and high cohesion. It needs to use encapsulation reasonable.  We can improve the reusability of software based on three-level: method, class and module. For instance, we can extract method or super class, define some helper class, devide modules by dependency.  The following diagram demonstrates how to apply template method pattern to reuse some codes in JUnit Framework:

image

Extensibility

The excellence structure of software should be extensible so that we can add functions without modifying the source code. There are two meaning of extensibility. First we don't add new features to expose it, that is an extensiblity internal.  We can decorate the target object or control it by providing a proxy object. Second is an extensiblity external. The inheritance and composition are the common approach. Of course, we don't forget the abstraction. For example, the Runnable interface in Java supports the extensiblity of business when you want to write the multi-thread program.

class MyThreadStart implements Runnable {
     public void run()  {
        //do something
    }
}

Thread controller = new Thread(new ThreadStart());
controller.start();

Separation

Concern separation is the most important principle for architecting architecture. The classic patterns which embody the concern separtion are layered architecture pattern and MVC pattern. The key element of separtion is that seperating changeful resposiblity from changeless object. That is core value of SRP also. Of course, we must focus on the collaboration between objects too. The following diagrams list my opinon about separation:  imageimage image

Change

One of the inevitable thing is change in the software development. So we must find the change point when we analyze the requirement. In my experience, I think these points always are changed as below:

1. Business Rule (Solution: Specification Pattern)

2. Algorithm and Strategy (Solution: Strategy Pattern)

3. Command and Request (Solution: Command Pattern)

4. Hardware Environment (Solution: Abstraction Layer or Gateway Pattern)

5. Protocol and Standard (Solution: Metadata)

6. Data Schema (Solutioin: Encapsulate Data or Information Hide)

7. Business Flow (Solution: Customize Workflow)

8. System Configuration (Solution: Metadata or Database)

9. User Interface and Presentation (Solution: Layered Pattern, MVC Pattern)

10. External Services (Solution: Abstraction Layer or Service Facade)

Simplicity

There are two important principles we have always to keep in mind. These are KISS(Keep it simple and stupid) and YAGNI(You aren't gonna need it). How to simplify the complex implemention? We can use encapsulation to hide the complex implementation. The abstraction is the other way. It might unify model, and elimilate the difference. As architect, most of them want to pursue the perfect solution. It's wrong! Many anti-patterns related with this idea, such as Analysis Paralysis, Accidental Complexity.

Consistency

So called "Consistency" includes interface, format, invoking way and solution. If we have consistant interface, so the implementation can be substituted. If we have consistant format, we can infer the overall design from the part of design. Consistant invoking way would help client understand the intention of service provider. Consistant solution is the basic of cooperation of team. For example, we can achieve the consistant invoking way by using composit pattern:

image Indirection

David Wheeler said:"All problems in computer science can be solved by another level of indirection". Indirection in software programming is achieved by delegation, abstraction and collaboration. Indirection can reduce dependence, hide the detail and simplify the client call. Many pattens are reflect the indirection thought, such as Facade Pattern, Mediator Pattern, Adapter Pattern, Strategy Pattern, Service Locator Pattern.

Friday, July 9, 2010

Hunt a new Job

I changed my job recently. When I worked in a new company, I found everything is not ok. I don't like my job responsibility. As current role, I need to go out on business often, and communication with some fresh guys who don't understand what is software developing. I felt I am a cheater. That's terrible.

I need change, but the new job can't give me new opportunity and challedge. Of course, the new job can't help me improve my ability. Don't hesitate, I want to hunt a new job.

I am back

Don't ask me the reason why I don't update my blog these days. Maybe I am lazy. In fact, I can't visit the wordpress normally in China. Fortunately, one of my freinds introduce one way to handle this issue, so I am back.

These days, I don't stop keeping my moving. I wrote and posted some articles about software in my chinese blog(http://www.agiledon.com). Well, I'll continue to write these with english version. Wait for me. Thanks.