Friday, May 16, 2014

What's wrong with Chinese downloads?

Here an example of the download statistics of Groovy 2.3.0 from bintray.com


Why are we receiving so many downloads from China?


Since the creation of JFrog, every time one of our user was providing popular content and downloads, we get hit by huge amount of queries from China.
We tried desperately to find a pattern in theses queries. A faulty download manager, may be the agent name will tell us how to fix this, the pattern of action, and so on. We kind of find a way to stop this, but still every year something new appears.

For info, the pattern is extremely damaging to our servers. A robot of some kind is opening thousands of requests to download something, then starts to get the first few bytes, but immediately stops and keep the connection open.

The issue is that using smart tools on our side to find the above pattern, will block good traffic based on AJAX and long running REST API. Our products (Artifactory and Bintray) needs many parallel connections and long running HTTP sockets to work correctly. So, we are a lot more vulnerable than a standard web site.

Still, I keep thinking! Why people are creating theses robots? Why from China?

Than it hit me!

By running theses robots, they may force us to take the decision to complete block Chinese traffic to our servers. And if we do this, what are the consequences?

Chinese entrepreneurs will create the equivalent of our services inside the firewall. Then the services will run on data centers controlled by the Chinese government and under Chinese law. And we will not be able to complain or fight back.

At the end of the day, we are the bad guys! We unilaterally decided to block China!

I'm wondering if this scenario actually happened to many other website like twitter, amazon, youtube, hulu or facebook, and so paved the ground for the equivalents to be created inside the great firewall.

Am I wrong?

Tuesday, July 5, 2011

Extended Enums usage

Since the re-launch of extended enums I'm paying attention in my everyday coding (yes I still write code :) if extended enums will help me.
Here are 2 new examples:
1) I found out that most of the time the name() of the enum is not what I need. I need it to map an XML or HTML tag, an external ID, an entry name in excel or simple type name in a JSON object. So I write something like:

public enum ConfigName {
ALL("local-all"),
INTERNAL("local-int"),
OR("local-int-ext");

private final String xmlKey;

LdapConfig(String xmlKey) {
this.xmlKey = xmlKey;
}

public String getXmlKey() {
return xmlKey;
}
}

I could remove the getter, and the IDE helping a lot writing the boiler plate code but why? Here is how it should look:
    public enum ConfigName extends AlternateEnumKey {
ALL("local-all"),
INTERNAL("local-int"),
OR("local-int-ext");
}

The extra feature here is that the name() of the enum (ALL, INTERNAL, OR) is a constant that is not recognized as such by the javac compiler. So:
    @XmlTag(tag = ConfigName.ALL)

will not compile and so:
    @XmlTag(tag = ConfigName.ALL.xmlKey)

will for sure not.

But with extended enum you'll have:
    public @interface XmlTag { AlternateEnumKey tag(); }

// The framework managing XmlTag will take the alternate key value
@XmlTag(tag = ConfigName.ALL)

2) Since extended enums also supports generics for enums, and I just have this issue associating also a long (ID) to an enums, you can now write:
    public enum ConfigName extends EnumPairExtension<Long, String> {
ALL(45L, "local-all"),
INTERNAL(56L, "local-int"),
OR(98L, "local-int-ext");
}

assert ConfigName.OR.a == 98L;

With this, parsing definitions are a lot cleaner to write.

Tuesday, June 14, 2011

A new push for extended enums!

At Devoxx09, Joe Darcy presented the status and future of the Coin project, and how changes to the language are selected and implemented (or vice versa). :)
During his talk, he showed the cost classification of a language change: trivial, small, medium, big, or huge, and emphasized the fact that each change is also a benefit (hard to measure a priori) that can be estimated as big, medium, or small.
So for example, the new loop syntax introduced in Java5 was a small change with big benefits—a no "brainer", let's do it!

However, in his talk he showed how "Extended Enums" were at least medium cost with a small benefit.

I started working on "Extended Enums" (previously "abstract enum") since the release of OpenJDK and the launch of the now defunct KSL (Kitchen Sink Language) in 2006. From the amount of hits this blog is getting on "extended enums", I know this issue is of big concern for many Java developers.
I developed a working solution, but stopped pushing for it for two main reasons:
  • This addition to the language is a change to the Java-type system. Moreover, it cannot be a small modification; it is at least a medium change.
  • Looking at Scala Traits or Fantom Mixin, I had the feeling that it was pushing Java too much, and perhaps in the wrong direction.


So I talked with Joe Darcy at Devoxx09 about all the things I discovered implementing this change to the javac compiler (and other needed changes to the JDK classes). It was clear that the change is medium size, but I disagree that the benefits are small.
The benefits of "Extended enums" as implemented today:
  • Ability for enum declaration to extend an actual abstract class
    This is the evident benefit, and it is a small benefit. Using delegation and/or in-lined anonymous classes is not too verbose and provides the same benefits. Still it is nicer and cleaner to have the normal OO inheritance.
  • Ability to use Generics in Enum classes
    With "Extended enums" you can have code like this:

    public enum ActionQuery<T extends Action> {
    ALL<Action> {
    public List<Action> getResults() {...}
    },
    EDIT_ACTION<EditAction> {
    public List<EditAction> getResults() {...}
    },
    VIEW_ACTION<ViewAction> {
    public List<ViewAction> getResults() {...}
    };
    public abstract List<T> getResults();
    }

    I find "Extended enums" very useful in organizing SQL queries and their results, playing with properties and their types, and so on.
  • The most important feature and the reason why I developed "Extended enums" was to have the ability to define annotation enum parameters without having to specify their list of values in advance. You can already see this issue in today's JPA specification. There is an enum FetchType that is fixed in the spec to LAZY and EAGER, but Hibernate also supports SUBSELECT, which is approximately between LAZY and EAGER. To support SUBSELECT, you need to use the Hibernate specific annotation in combination with the standard one. If the FetchType was an abstract enum, the JPA specification does not need to enforce a well-defined list, but could have a proposed DefaultFetchType and let JPA implementation and application developers define a new enum with their desired list of FetchType. This already works great in the "abstract enum" implementation and provides me with great benefits in many other areas: (such as BindingType in JSR-299 Context and Dependency Injection, Cache declaration using enum instead of error prone string for region, Group in JSR-303 Bean Validation using user defined enums instead of empty interfaces, and more).


From my point of view (and I think/hope I'm not alone), Joe Darcy missed the benefit point of the extended enum. It is a big benefit to the Java language.
This was and is my position for some time. What pushed me to re-launch "Vote for Extended Enums for the Coin project!", is of course Christof May from soplets.org (which setup the extended-enums site: http://www.extended-enums.org/), and the fact that I found a way to make the change a "small" one. Until now, I was sure that to implement this correctly a new flag was needed in the class byte code, and many changes to the Java type management were necessary.

So, if you are interested or want to learn more please check the extended enums web site: http://www.extended-enums.org/