My take: I try to write it DRY first. If I fail to come up with a good intuitive abstraction after half an hour, I just write it simple and copy code.
The next day or later I come back to the code and sometimes I find a neat abstraction then, which just needed more context. Sometimes I can get rid of the whole section too...
My rule of thumb is wait to generalize something until it is repeated 3 times. If I try before I can't really know what the problem is. But if it's something that's repeated across projects, sure I tackle it right away, but then maybe it should be open source?
Half an hour? When you're first writing the code, you should know immediately if you're going to need to repeat it and what the abstraction should be. If you don't, then don't waste your time. Later, if it turns out that you actually do need to repeat the code, it should be clear at that point what the abstraction should be.
Let the actual need for duplication guide you in finding abstractions, so you don't waste your time and produce difficult-to-follow code for no reason.
The next day or later I come back to the code and sometimes I find a neat abstraction then, which just needed more context. Sometimes I can get rid of the whole section too...
It all... Depends.