Disabling nagle in python: how to do it the right way? - sockets

I need to disable nagle algorithm in python2.6.
I found out that patching HTTPConnection in httplib.py that way
def connect(self):
"""Connect to the host and port specified in __init__."""
self.sock = socket.create_connection((self.host,self.port),
self.timeout)
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) # added line
does the trick.
Obviously, I would like to avoid patching system lib if possible. So, the question is: what is right way to do such thing? (I'm pretty new to python and can be easily missing some obvious solution here)

Please note that if using the socket library directly, the following is sufficient:
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
I append this information to the accepted answer because it satisfies the information need that brought me here.

It's not possible to change the socket options that httplib specifies, and it's not possible to pass in your own socket object either. In my opinion this sort of lack of flexibility is the biggest weakness of most of the Python HTTP libraries. For example, prior to Python 2.6 it wasn't even possible to specify a timeout for the connection (except by using socket.setdefaulttimeout() globally, which wasn't very clean).
If you don't mind external dependencies, it looks like httplib2 already has TCP_NODELAY specified.
You could monkey-patch the library. Because python is a dynamic language and more or less everything is done as a namespace lookup at runtime, you can simply replace the appropriate method on the relevant class:
:::python
import httplib
def patch_httplib():
orig_connect = httplib.HTTPConnection.connect
def my_connect(self):
orig_connect(self)
self.sock.setsockopt(...)
However, this is extremely error-prone as it means that your code becomes quite specific to a particular Python version, as these library functions and classes do change. For example, in 2.7 there's a _tunnel() method called which uses the socket, so you'd want to hook in the middle of the connect() method - monkey-patching makes that extremely tricky.
In short, I don't think there's an easy answer, I'm afraid.

Related

How does Server.call work in elixir-mongo?

I'm learning Elixir and attempting to use the elixir-mongo library. During the auth/1 command, A the function uses Server.call, piping in the MongoDB request string. looking at the Mongo.Server class, it does not appear to be an actual genserver, nor have a method to match call/1. How is this working?
With high probability it doesn't work. Mongo.Server module doesn't export call function. There are no macros that generate it magically. My guess is that master branch is currently broken. If you are using the library and want to dig into the sources make sure you are looking at the same tag as the version you are using in your project.
Also, there are no classes and methods in Elixir. There are modules and functions :)

How to write a value from the response to a file in Gatling?

I have a script which creates new referenceId each time its executed. I used
.check(regex("orders.(.*?)\"").saveAs("referenceId")))
to extract the referenceId. Now, how can I write/append it to a file without impacting the script even if I run it as a load test?
I used session in .exec to write my value into a file. Here it is:
.exec( session => {
scala.tools.nsc.io.File("../user-files/data/refenceId.csv").appendAll(session("refenceId").as[String]+"\n")
session}
)
You solution works, but...
First of all do not use anything (if you don't have to) from scala.tools.nsc.io package. It is internal package only for Scala compiler. It is not public API included in Scala runtime library (official Scaladoc). More about the topic here. Scala do not have any own abstraction for writing to file, hence one need to use normal java.io.File & co.
Secondly opening a file in each execution can (may not) slow down your load-test. It strongly depends on at which rate you are making the requests. At higher rates you can experience contention when more concurrent executions will be trying to write to same file. Simplest solution to this is to write to different files, but you can still run out of maximum possible number of opened files. Another solution is to use shared java.io.FileOutputStream resp. java.io.FileWriter to desired target file with proper synchronisation (will be accessed from various threads), which is still blocking IO. Yet another solution will be use Java NIO API to write to shared file via Channel (non-blocking) or OutputStream (not sure if non-blocking).
Of course solutions differ in difficulty of implementation.

Elixir Protocols in Erlang & a Strange Warning

I wanted to write something like ((IStringer)object).ToString() (in C#) in Erlang. After some studying I've learnt that Elixir has something called Protocols that pretty much resembles the same thing of C# (in an inside-out manner). Then I came up with this idea/code in Erlang - which is nice enough to me like:
?stringer(my_val):to_string().
And it either returns the expected value or not_implemented atom!
But 2 questions:
1 - Why nobody use this or promote things based on stateful modules in Erlang? (OTP aside and from talking to some Erlangers they did not know that actually OTP is built around this! So really there is a need to change how Erlang is being taught and promoted. It's possible that I am confused.).
2 - Why I get this warning? That call actually can never fails.
The warning:
stringer.erl:18: Warning: invalid module and/or function name; this call will always fail
stringer.erl:19: Warning: invalid module and/or function name; this call will always fail
stringer.erl:20: Warning: invalid module and/or function name; this call will always fail
The code:
-module(stringer).
-export([to_string/1,sample/0]).
-define(stringer(V), {stringer, V}).
to_string({stringer, V}) when is_list(V) ->
to_string(V, nop);
to_string({stringer, V}) when is_atom(V) ->
to_string(V, nop);
to_string({stringer, _V}) ->
not_implemented.
to_string(V, _Nop) ->
Buffer = io_lib:format("~p",[V]),
lists:flatten(Buffer).
sample() ->
io:format("~p~n", [?stringer([1,2]):to_string()]),
io:format("~p~n", [?stringer(cute_atom):to_string()]),
io:format("~p~n", [?stringer(13):to_string()]).
And the output is:
"[1,2]"
"cute_atom"
not_implemented
I am doing this on Erlang R16 B2 (V5.10.3) 32 bit on Windows 8 64 bit.
The warning you see is an Erlang bug. If Erlang sees you are invoking a function in a literal tuple, it shows the warning. I have seen this while working with Elixir, I have silenced it in Elixir's compiler but forgot to report it to the Erlang team as a bug. Sorry.
The stateful module thing is actually avoided in Erlang by the majority of developers. They were added to support a feature called "parameterized modules", which has then since been removed, but the underlying dispatching mechanism still exists. If you search the Erlang Questions mailing list you can find plenty of discussion on the topic. Note that protocols in Elixir are not implemented like that though.
In fact, it seems your implementation does not seem to add anything compared to a regular function. For example, you could have simply written:
to_string(V) when is_list(V); is_atom(V) ->
Buffer = io_lib:format("~p",[V]),
lists:flatten(Buffer);
to_string(V) ->
not_implemented.
and called the function directly. Your implementation is simply using the classic ad-hoc polymorphism provided by Erlang at the end of the day. The limitation of this approach is that, since dispatch is hardcoded to ?stringer, the only way to extend the to_string/1 behaviour to work with a new data type is to reimplement and replace the whole stringer module.
Here is an example of an issue that helps you ponder about this: if application A defines a "protocol" named stringer, how can applications B and C extend this protocol to their own data types and all be used by application D without loss of functionality?
In very simple words, the way protocols work in Elixir is by making the stringer module an intermediate dispatch module. So the stringer module actually works like this:
to_string(V) when is_list(V) ->
string_list:to_string(V);
to_string(A) when is_atom(A) ->
string_atom:to_string(A);
%% ...
to_string(A) when is_tuple(A) ->
string_tuple:to_string(A).
and imagine that code is wrapped around something that checks if the module exists and fails accordingly if not. Of course, all of that is defined automatically for you by simply defining the protocol. There is also a mechanism (called consolidation) to compile protocols down to a fast dispatch mechanism on releases.

Scala RemoteActor multiple network interfaces

Method alive(port) in RemoteActor does not take IP address as parameter.
It constructs internally a TcpService object which assings the IP address by calling Java's InetAddress.getLocalHost().getHostAddress() which returns the IP of the first available interface.
This is causing problems on machines with multiple network interfaces as it might return the wrong IP address.
Is there any possible way to overcome this issue.
Thanks.
Good question. It depends on how much you want to invest in a solution. I can imagine two ways:
1) The first way to change the default implementation is to write something better yourself. It's not that hard though since all the code for the remote actor library is available on GitHub.
My suggestion would be to re-implement parts of the TcpSerice class, especially line 73 to something like:
private val internalNode = {
val interfaces = NetworkInterface.getNetworkInterfaces()
val interface = ... // find the right interface here
val addresses = interface.getInetAddresses()
val address = ... // find the right address here
new Node(address, port)
}
This method also allows you to customize other stuff if you'd like to add or change something else.
2) The other (and probably simpler) method would be to avoid using the default implementation all together and instead use the very popular actor-framework akka. Akka provides a great deal of additional features, but also efficiency and robustness. If you look on their GitHub and the Server class, you'll see that the host is actually read from a global config-entry "hostname".
A detailed guide on how to manipulate the configs are given here. You should be able to use code similar to the above to find the right interface and address.
Hope that helps!

What is scala.mobile supposed to accomplish?

...and why has the package this misleading name (I assumed it had something to do with JavaME or mobile/smart phones)?
I found no references on the internet about scala.mobile.Code or scala.mobile.Location at all nor did I manage to do anything with those classes except getting ClassCastExcetions or NoSuchMethodErrors.
Actually there is not even a single test against scala.mobile in the Scala's test tree which could help understanding that code.
The classes really smell like they were forgotten in the source tree a long time ago and got accidentally released since that.
Maybe I just missed something about them?
Update:
scala.mobile was removed in Scala 2.9.
I just checked the source code.
When Scala changed the name mangling of class files a few years ago and it seems people forgot to update these classes accordingly.
So my answer would be:
At least Location has no purpose, because it is not possible to get anything sensible out of it (except exceptions) and Code without Location is severely limited. It works though if you pass the class literal to Code directly:
import scala.mobile._
val c = new Code(classOf[scala.collection.mutable.StringBuilder])
c.apply[StringBuilder, String]("append")("Foo")
c.apply[String]("toString")() // returns "Foo"
c.apply[Int]("length")() // returns 3
Looks like yet-another implementation in the standard library of reflection-slightly-nicer.
The description of Location pretty much explains what that is about:
The class Location provides a create method to instantiate objects
from a network location by specifying the URL address of the jar/class file.
It might be used by remote actors. Maybe.
As for why it has this misleading name? Well, back in 2004 smart phones had really low penetration, so maybe the association wasn't all that strong.